如何在Go中将JSON固定长度数组解析为自定义结构体?
Go解析JSON数组数组为结构体数组的解决方案
问题背景
你的JSON数据格式如下:
{ // 其他数据... "series": [ [1709120579, 23.12], [1709120655, 24.69], [1709120660, 25.01], // 更多数据.. ], // 其他数据... }
希望将其解析为Go结构体:
type DataPoint struct { Timestamp int64 Value float64 } type JsonData struct { // 其他字段... Series []DataPoint `json:"series"` // 其他字段... }
但测试代码运行时出现错误:
Error unmarshalling JSON: json: cannot unmarshal array into Go struct field JsonData.data of type main.DataPoint
错误原因
JSON中series的每个元素是长度为2的数组,而Go默认会将结构体对应为JSON键值对对象。直接用[]DataPoint解析时,系统会尝试把数组转换成结构体,自然触发类型不匹配的错误。
解决方案
给DataPoint类型实现json.Unmarshaler接口,自定义解析逻辑,把JSON数组映射为结构体字段:
完整可运行代码
package main import ( "encoding/json" "fmt" ) type DataPoint struct { Timestamp int64 Value float64 } // 自定义JSON解析逻辑,实现json.Unmarshaler接口 func (dp *DataPoint) UnmarshalJSON(data []byte) error { // 先将JSON数组解析为临时切片 var tempSlice []interface{} if err := json.Unmarshal(data, &tempSlice); err != nil { return err } // 校验数组长度是否符合预期 if len(tempSlice) != 2 { return fmt.Errorf("数据点格式错误,需包含2个元素") } // 转换时间戳:JSON数字默认解析为float64,需转成int64 ts, ok := tempSlice[0].(float64) if !ok { return fmt.Errorf("时间戳类型无效") } dp.Timestamp = int64(ts) // 转换数值 val, ok := tempSlice[1].(float64) if !ok { return fmt.Errorf("数值类型无效") } dp.Value = val return nil } type JsonData struct { Series []DataPoint `json:"series"` } func main() { jsonData := []byte(`{"series":[[1709120579,23.12],[1709120655,24.69],[1709120660,25.01]]}`) var result JsonData err := json.Unmarshal(jsonData, &result) if err != nil { fmt.Println("解析JSON错误:", err) return } // 验证解析结果 fmt.Printf("第一个数据点:时间戳=%d,数值=%.2f\n", result.Series[0].Timestamp, result.Series[0].Value) }
代码说明
- 实现
UnmarshalJSON方法后,Go的json.Unmarshal会自动调用该方法处理每个DataPoint的解析 - JSON中的数字默认被解析为
float64,因此需要手动转换时间戳为int64 - 添加了格式校验,避免非法数据导致程序崩溃
内容的提问来源于stack exchange,提问作者Allstreamer_
相关产品推荐
相关产品推荐

