如何将含未标记字段的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
相关产品推荐
相关产品推荐

