去结构字段未定义
Go Struct Fields Undefined
在创建 REST 的同时学习 Go API。当我在底部两次使用它访问字段时出现错误 undefined: authDetails
。我知道它设置在一个可能无法执行的分支中。我试过将它移出分支,或者在上面用 var authDetails auth.AccessDetails
声明它,然后再设置值。我也试过将赋值移到大括号之外,但无论我做什么,它似乎都没有将条件块内的值带到我尝试使用它们的地方。
我想我对范围有一些误解,如果有人能帮助我理解问题所在,那将是一个巨大的帮助。
结构定义为:
type AccessDetails struct {
AccessUuid string
UserId uint64
}
代码是:
func (server *Server) GetTokenUserIDFromRequest(r *http.Request) (uint64, error) {
var authDetails auth.AccessDetails
tokenString := auth.ExtractToken(r)
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return 0, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
return []byte(os.Getenv("API_SECRET")), nil
})
if err != nil {
return 0, err
}
claims, ok := token.Claims.(jwt.MapClaims)
if ok && token.Valid {
accessUuid, ok := claims["access_uuid"].(string)
if !ok {
return 0, errors.New("token not valid, cannot retrieve access_uuid")
}
userid, err := strconv.ParseUint(fmt.Sprintf("%.0f", claims["user_id"]), 10, 64)
if err != nil {
return 0, err
}
authDetails := &auth.AccessDetails{
AccessUuid: accessUuid,
UserId: userid,
}
}
redisuserid, err := server.RedisClient.Get(authDetails.AccessUuid).Result()
if err != nil {
return 0, err
}
userID, _ := strconv.ParseUint(redisuserid, 10, 64)
if userID != authDetails.UserId {
return 0, errors.New("userid from token does not match userid from database")
}
return userID, nil
}
您正在 if
块中重新声明 authDetails
,而不是设置在外部范围声明的值。语言规范中的相关部分是:
https://golang.org/ref/spec#Short_variable_declarations
而不是authDetails:=...
使用authDetails=...
,所以它成为一个赋值,而不是一个声明。
在创建 REST 的同时学习 Go API。当我在底部两次使用它访问字段时出现错误 undefined: authDetails
。我知道它设置在一个可能无法执行的分支中。我试过将它移出分支,或者在上面用 var authDetails auth.AccessDetails
声明它,然后再设置值。我也试过将赋值移到大括号之外,但无论我做什么,它似乎都没有将条件块内的值带到我尝试使用它们的地方。
我想我对范围有一些误解,如果有人能帮助我理解问题所在,那将是一个巨大的帮助。
结构定义为:
type AccessDetails struct {
AccessUuid string
UserId uint64
}
代码是:
func (server *Server) GetTokenUserIDFromRequest(r *http.Request) (uint64, error) {
var authDetails auth.AccessDetails
tokenString := auth.ExtractToken(r)
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return 0, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
return []byte(os.Getenv("API_SECRET")), nil
})
if err != nil {
return 0, err
}
claims, ok := token.Claims.(jwt.MapClaims)
if ok && token.Valid {
accessUuid, ok := claims["access_uuid"].(string)
if !ok {
return 0, errors.New("token not valid, cannot retrieve access_uuid")
}
userid, err := strconv.ParseUint(fmt.Sprintf("%.0f", claims["user_id"]), 10, 64)
if err != nil {
return 0, err
}
authDetails := &auth.AccessDetails{
AccessUuid: accessUuid,
UserId: userid,
}
}
redisuserid, err := server.RedisClient.Get(authDetails.AccessUuid).Result()
if err != nil {
return 0, err
}
userID, _ := strconv.ParseUint(redisuserid, 10, 64)
if userID != authDetails.UserId {
return 0, errors.New("userid from token does not match userid from database")
}
return userID, nil
}
您正在 if
块中重新声明 authDetails
,而不是设置在外部范围声明的值。语言规范中的相关部分是:
https://golang.org/ref/spec#Short_variable_declarations
而不是authDetails:=...
使用authDetails=...
,所以它成为一个赋值,而不是一个声明。