json: cannot unmarshal string into Go struct field ***.***.***.Code of type int

2025年12月16日 18:57 状态: processing

🚨 错误信息

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验证

  • 在API文档中明确字段类型
  • 使用JSON Schema或OpenAPI规范定义接口
  • 在开发阶段使用静态类型检查工具

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接口开发,建议方案二结合方案三,既能处理多种数据格式,又能保持类型安全。