You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将含未标记字段的JSON文件反序列化为Go结构体?

解决方案:自定义反序列化处理encodings字段

要处理这种嵌套数组到结构体的反序列化,最直接的方式是给EncodedData实现json.Unmarshaler接口,自定义反序列化逻辑——默认的encoding/json没法自动把数组结构映射到你的结构体,而且第三个元素还是JSON编码的字节数组字符串,需要额外解析。

步骤1:修正结构体字段

Go的encoding/json只能处理导出字段(首字母大写),所以先调整EncodedData的定义:

type EncodedData struct {
    Field3  uint64 `json:"field3"`
    Field4  uint64 `json:"field4"`
    Encoded []byte `json:"encoded"`
}

步骤2:实现自定义反序列化方法

给EncodedData添加UnmarshalJSON方法,手动解析嵌套数组的每个元素:

import (
    "encoding/json"
    "fmt"
    "log"
)

func (e *EncodedData) UnmarshalJSON(data []byte) error {
    // 先把JSON数组反序列化为临时切片,适配数组的松散类型
    var temp []interface{}
    if err := json.Unmarshal(data, &temp); err != nil {
        return err
    }

    // 校验数组长度是否符合预期
    if len(temp) != 3 {
        return fmt.Errorf("invalid encoded data: expected 3 elements, got %d", len(temp))
    }

    // 提取并转换第一个元素为uint64
    field3Val, ok := temp[0].(float64)
    if !ok {
        return fmt.Errorf("field3 is not a numeric value")
    }
    e.Field3 = uint64(field3Val)

    // 提取并转换第二个元素为uint64
    field4Val, ok := temp[1].(float64)
    if !ok {
        return fmt.Errorf("field4 is not a numeric value")
    }
    e.Field4 = uint64(field4Val)

    // 提取第三个字符串元素,再反序列化为[]byte
    encodedStr, ok := temp[2].(string)
    if !ok {
        return fmt.Errorf("encoded field is not a string")
    }
    if err := json.Unmarshal([]byte(encodedStr), &e.Encoded); err != nil {
        return fmt.Errorf("failed to parse encoded data: %w", err)
    }

    return nil
}

步骤3:正常反序列化整个JSON

现在你的MyData结构体可以直接用来反序列化完整的JSON数据了,测试示例:

type MyData struct {
    Field1    uint64         `json:"field1"`
    Field2    uint64         `json:"field2"`
    Encodings []EncodedData `json:"encodings"`
}

func main() {
    jsonContent := `{
        "field1": 123,
        "field2": 345,
        "encodings": [
          [
              123456,
              567890,
              "[123, 234, 15, 0]"
          ]
        ]
    }`

    var result MyData
    if err := json.Unmarshal([]byte(jsonContent), &result); err != nil {
        log.Fatalf("Unmarshal failed: %v", err)
    }

    // 打印结果验证
    log.Printf("Field1: %d", result.Field1)
    log.Printf("Field2: %d", result.Field2)
    log.Printf("EncodedData[0].Field3: %d", result.Encodings[0].Field3)
    log.Printf("EncodedData[0].Field4: %d", result.Encodings[0].Field4)
    log.Printf("EncodedData[0].Encoded: %v", result.Encodings[0].Encoded)
}

运行后会输出:

2024/xx/xx xx:xx:xx Field1: 123
2024/xx/xx xx:xx:xx Field2: 345
2024/xx/xx xx:xx:xx EncodedData[0].Field3: 123456
2024/xx/xx xx:xx:xx EncodedData[0].Field4: 567890
2024/xx/xx xx:xx:xx EncodedData[0].Encoded: [123 234 15 0]

内容的提问来源于stack exchange,提问作者Ken P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 06:57:21