Golang中对象创建失败的原因有哪些
Golang中对象创建失败的原因有哪些 我正在尝试为一个开源产品实现单点登录功能,但一直遇到一个阻碍我的错误。我想知道是否有人能告诉我,这是否是Go语言中需要我注意的某些特性(我对这门语言没有经验)。

我通过令牌传递了上述字段,然后对象如下所示。每次测试单点登录功能时,这个对象似乎都是空的。是否每个字段都必须存在,对象才能被正确创建?
type User struct {
ExternalID string `json:"sub"`
Name string `json:"name"`
Email string `json:"email"`
EmailVerified bool `json:"email_verified"`
UserInfoClaims map[string]interface{} `json:"user_info_claims"`
}
非常欢迎任何建议或解释。
更多关于Golang中对象创建失败的原因有哪些的实战教程也可以访问 https://www.itying.com/category-94-b0.html
您检查过 UnmarshalJSON() 方法是否返回错误吗?
更多关于Golang中对象创建失败的原因有哪些的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
(我对这门语言没有经验)
正如 @mje 所说,最好展示一下你目前尝试过的内容。
Jake_Murphy:
建议
在不确切知道您具体在做什么的情况下,很难判断。您能发布一个小的示例代码吗?
Jake_Murphy:
解释
Go 的 JSON 解码器会忽略 JSON 对象中那些在您的目标结构体中没有对应字段的字段。如果 JSON 对象中不存在某个字段,它也会让结构体字段保持初始化为零值。根据您发布的示例数据和结构体代码,您结构体的前四个字段应该会被填充。
大家好,感谢如此快速的回复。
我受限于必须使用一个企业级 Kubernetes 环境,该环境有很多限制,我无法在本地复现,因此我没有机会像往常那样逐步调试代码。
我想再问一个 Go 问题,这可能有助于我更好地理解代码为何有效或无效。
Go 是否有内置的机制会自动使用这个 UnmarshalJSON 方法,还是应该在某个地方显式调用它?

如果它应该在某个地方被显式调用,我可能需要在 Git 仓库上提交一个错误报告。
从你提供的代码和错误信息来看,这确实是Go语言JSON反序列化的一个常见问题。主要原因是JSON字段类型与Go结构体字段类型不匹配。
在你的情况下,email_verified字段在JSON中是字符串类型("true"或"false"),但Go结构体中定义为bool类型。Go的JSON包无法自动将字符串转换为布尔值。
以下是修复方案:
type User struct {
ExternalID string `json:"sub"`
Name string `json:"name"`
Email string `json:"email"`
EmailVerified bool `json:"email_verified,string"` // 添加,string标签
UserInfoClaims map[string]interface{} `json:"user_info_claims"`
}
或者,如果JSON中的email_verified字段可能缺失或为null,可以使用指针类型:
type User struct {
ExternalID string `json:"sub"`
Name string `json:"name"`
Email string `json:"email"`
EmailVerified *bool `json:"email_verified,omitempty"`
UserInfoClaims map[string]interface{} `json:"user_info_claims"`
}
如果JSON中的布尔值确实是字符串格式,但你不能修改结构体标签,可以实现自定义的JSON反序列化:
type User struct {
ExternalID string `json:"sub"`
Name string `json:"name"`
Email string `json:"email"`
EmailVerified bool `json:"email_verified"`
UserInfoClaims map[string]interface{} `json:"user_info_claims"`
}
func (u *User) UnmarshalJSON(data []byte) error {
type Alias User
aux := &struct {
EmailVerified string `json:"email_verified"`
*Alias
}{
Alias: (*Alias)(u),
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
// 手动处理字符串到布尔值的转换
if aux.EmailVerified == "true" {
u.EmailVerified = true
} else {
u.EmailVerified = false
}
return nil
}
关于字段是否必须存在的问题:默认情况下,JSON反序列化时缺失的字段会被设置为零值(空字符串、false、0等)。如果你需要验证必需字段,可以在反序列化后手动检查:
var user User
if err := json.Unmarshal(data, &user); err != nil {
// 处理错误
}
// 检查必需字段
if user.ExternalID == "" || user.Email == "" {
return errors.New("required fields missing")
}
或者使用required标签配合验证库:
import "github.com/go-playground/validator/v10"
type User struct {
ExternalID string `json:"sub" validate:"required"`
Name string `json:"name"`
Email string `json:"email" validate:"required,email"`
EmailVerified bool `json:"email_verified,string"`
UserInfoClaims map[string]interface{} `json:"user_info_claims"`
}
func main() {
validate := validator.New()
var user User
if err := json.Unmarshal(data, &user); err != nil {
// 处理错误
}
if err := validate.Struct(user); err != nil {
// 验证失败
}
}
错误信息中的json: cannot unmarshal string into Go struct field User.email_verified of type bool明确指出了问题所在:JSON中的字符串无法反序列化为Go的布尔类型。



