Golang中如何将一个函数的返回值传递给另一个函数

Golang中如何将一个函数的返回值传递给另一个函数 一个包中有两个函数。

func ArtToken(w http.ResponseWriter, r *http.Request) {

    c, err := r.Cookie("Visitor")
    if err != nil {
        if err == http.ErrNoCookie {
            w.WriteHeader(http.StatusUnauthorized)
            return
        }
        w.WriteHeader(http.StatusBadRequest)
        return
    }

    tknStr := c.Value
    claims := &Claims{}

    token, err := jwt.ParseWithClaims(tknStr, claims, func(token *jwt.Token) (any, error) {
        return key, nil
    })

    if err != nil {
        if err == jwt.ErrSignatureInvalid {
            w.WriteHeader(http.StatusUnauthorized)
            return
        }
        w.WriteHeader(http.StatusBadRequest)
        return
    }
    if !token.Valid {
        w.WriteHeader(http.StatusUnauthorized)
        return
    }

    return
}

将函数 ArtToken() 的结果用于函数 Creativity() 中时出错。 错误 staticcheck: article\creativity.go:25:22: ArtToken(w, r) (无返回值) 被用作值

// creativity.go
func Creativity(w http.ResponseWriter, r *http.Request) {

    tpl = template.Must(template.ParseFiles("./tpl/art/creativity.html"))

    if r.Method == "POST" {
        user := CreatArticle{
            Title: r.FormValue("title"),
            Description: r.FormValue("description"),
        }

        sqlStatement := `INSERT INTO article (title, description, author_id, created_at) VALUES ($1,$2,$3,$4)`

        var claims = ArtToken(w,r)

        _, err := db.Exec(sqlStatement, user.Title, user.Description, claims.User_id, time.Now())
        if err != nil {
            w.WriteHeader(http.StatusBadRequest)
            panic(err)
        }
    }
    tpl.Execute(w, nil)
}

更多关于Golang中如何将一个函数的返回值传递给另一个函数的实战教程也可以访问 https://www.itying.com/category-94-b0.html

8 回复

ArtToken 函数中的所有 return 语句都需要返回一个指向 Claim 对象的指针,或者返回 nil。目前看来,其中许多语句没有返回任何内容。

更多关于Golang中如何将一个函数的返回值传递给另一个函数的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


w http.ResponseWriter

另外,我发现你的 ArtToken 函数中的参数 w 是按值传递的,而不是按引用传递的。 因此,你在 ArtToken 中调用的 WriteHeader 不会对你的主函数产生任何影响。

返回值过多

这是因为你需要声明 ArtToken 函数返回 *Claims

func ArtToken(w http.ResponseWriter, r *http.Request) {

替换为

func ArtToken(w http.ResponseWriter, r *http.Request) *Claims {

是的,我原本打算从 Art Token 返回 Claims 对象。 但是使用

return claims
article\main.go:74:12: 返回值过多
        实际为 (*Claims)
        期望为 ()

尽管如此,但使用

    tpl = template.Must(template.ParseFiles("./tpl/auth.html"))
..
tpl.Execute(w, claims)

它工作得很好

ArtToken 函数没有返回任何值,但在 Creativity 函数中调用它时,其(不存在的)返回值被赋值给了 claims。我猜你原本是打算让 ArtToken 返回一个 Claims 对象。

所以应该是类似这样:

func ArtToken(w http.ResponseWriter, r *http.Request) *Claims {
    ...
    ...
    return claims
}
article\main.go:48:13: not enough return values
        have ()
        want (*Claims)
article\main.go:51:9: not enough return values
        have ()
        want (*Claims)
article\main.go:64:13: not enough return values
        have ()
        want (*Claims)
article\main.go:67:9: not enough return values
        have ()
        want (*Claims)
article\main.go:71:9: not enough return values
        have ()
        want (*Claims)
type Claims struct {
    User_id int `json:"user_id"`
    Email string `json:"email"`
    jwt.RegisteredClaims
}

第一个错误是:在函数(Method == “POST”)中引用了函数(Method == “GET”)。第二个错误是针对您指出的所有内容……但最主要的是:

    token, err := jwt.ParseWithClaims(tknStr, claims, func(token *jwt.Token) (interface{}, error) {
        return []byte(os.Getenv("JWT_SECRET")), nil
    })

不正确的语句:

..
var key = []byte(os.Getenv("JWT_SECRET"))
..
func
    token, err := jwt.ParseWithClaims(tknStr, claims, func(token *jwt.Token) (any, error) {
        return key, nil
    })

在Golang中,ArtToken函数没有返回值,所以无法直接将其结果传递给Creativity函数。你需要修改ArtToken函数,让它返回*Claims类型的值。以下是修改后的代码:

func ArtToken(w http.ResponseWriter, r *http.Request) (*Claims, error) {
    c, err := r.Cookie("Visitor")
    if err != nil {
        if err == http.ErrNoCookie {
            w.WriteHeader(http.StatusUnauthorized)
            return nil, err
        }
        w.WriteHeader(http.StatusBadRequest)
        return nil, err
    }

    tknStr := c.Value
    claims := &Claims{}

    token, err := jwt.ParseWithClaims(tknStr, claims, func(token *jwt.Token) (any, error) {
        return key, nil
    })

    if err != nil {
        if err == jwt.ErrSignatureInvalid {
            w.WriteHeader(http.StatusUnauthorized)
            return nil, err
        }
        w.WriteHeader(http.StatusBadRequest)
        return nil, err
    }
    if !token.Valid {
        w.WriteHeader(http.StatusUnauthorized)
        return nil, fmt.Errorf("invalid token")
    }

    return claims, nil
}

然后在Creativity函数中正确处理返回值:

func Creativity(w http.ResponseWriter, r *http.Request) {
    tpl := template.Must(template.ParseFiles("./tpl/art/creativity.html"))

    if r.Method == "POST" {
        user := CreatArticle{
            Title:       r.FormValue("title"),
            Description: r.FormValue("description"),
        }

        sqlStatement := `INSERT INTO article (title, description, author_id, created_at) VALUES ($1,$2,$3,$4)`

        claims, err := ArtToken(w, r)
        if err != nil {
            // 处理认证错误
            w.WriteHeader(http.StatusUnauthorized)
            return
        }

        _, err = db.Exec(sqlStatement, user.Title, user.Description, claims.User_id, time.Now())
        if err != nil {
            w.WriteHeader(http.StatusBadRequest)
            panic(err)
        }
    }
    tpl.Execute(w, nil)
}

这样修改后,ArtToken函数会返回认证成功后的claims对象和可能的错误,Creativity函数就可以正确使用这些返回值了。

回到顶部