json: cannot unmarshal string into Go struct field ***.***.***.Code of type int
🚨 错误信息
json: cannot unmarshal string into Go struct field ***.***.***.Code of type int
🤖 AI解决方案
报错分析报告
错误翻译
原文:json: cannot unmarshal string into Go struct field ***.***.***.Code of type int
译文:JSON:无法将字符串反序列化到Go结构体字段 ***.***.***.Code 的 int 类型中
原因分析
这是Go语言中JSON反序列化时的类型不匹配错误:
- 根本原因:JSON数据中的某个字段值是字符串类型,但Go结构体定义中对应的字段是int类型
- 具体位置:结构体字段路径为
..*.Code(实际字段路径已被星号隐藏) - 错误场景:使用
json.Unmarshal()或类似方法解析JSON时,JSON中的字符串值无法自动转换为Go的int类型
解决方案
方案一:修改JSON数据(如果可控制数据源)
{
"Code": 200 // 改为数字而非字符串
}
方案二:修改Go结构体定义
// 错误的结构体定义
type YourStruct struct {
Code int `json:"Code"` // ❌ 定义为int但收到字符串
}
// 修复后的结构体定义
type YourStruct struct {
Code int `json:"Code"` // ✅ 方法1:保持int,确保JSON中为数字
}
// 或者使用json.Number(如果数据可能是字符串形式的数字)
type YourStruct struct {
Code json.Number `json:"Code"` // ✅ 方法2:使用json.Number
}
// 或者先定义为字符串再转换
type YourStruct struct {
Code string `json:"Code"` // ✅ 方法3:定义为字符串,后续转换
}
// 然后手动转换
codeInt, err := strconv.Atoi(yourStruct.Code)
方案三:自定义JSON反序列化
type YourStruct struct {
Code int `json:"Code"`
}
func (s *YourStruct) UnmarshalJSON(data []byte) error {
// 临时结构体用于处理字符串或数字
type Alias YourStruct
aux := &struct {
Code interface{} `json:"Code"`
*Alias
}{
Alias: (*Alias)(s),
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
// 处理不同类型的Code值
switch v := aux.Code.(type) {
case float64:
s.Code = int(v)
case string:
if code, err := strconv.Atoi(v); err == nil {
s.Code = code
} else {
return fmt.Errorf("Code必须是可转换为int的数字或字符串")
}
default:
return fmt.Errorf("Code必须是数字或字符串")
}
return nil
}
️ 预防措施
1. 使用严格JSON Schema验证
2. 实现防御性编程
// 创建测试验证函数
func ValidateJSON(jsonStr string, target interface{}) error {
// 先进行语法检查
if !json.Valid([]byte(jsonStr)) {
return fmt.Errorf("无效的JSON格式")
}
// 使用json.RawMessage延迟反序列化
var raw map[string]json.RawMessage
if err := json.Unmarshal([]byte(jsonStr), &raw); err != nil {
return err
}
// 检查关键字段类型
if codeData, ok := raw["Code"]; ok {
// 尝试解析为字符串和数字
var codeStr string
var codeNum int
// 先尝试字符串
if err := json.Unmarshal(codeData, &codeStr); err == nil {
// 验证字符串是否为有效数字
if _, err := strconv.Atoi(codeStr); err != nil {
return fmt.Errorf("Code字段的值'%s'无法转换为整数", codeStr)
}
} else if err := json.Unmarshal(codeData, &codeNum); err != nil {
return fmt.Errorf("Code字段必须是数字或可转换为数字的字符串")
}
}
// 如果所有检查通过,执行实际反序列化
return json.Unmarshal([]byte(jsonStr), target)
}
---
建议:根据您的实际情况选择最适合的解决方案。如果是API接口开发,建议方案二结合方案三,既能处理多种数据格式,又能保持类型安全。