Go如何反序列化混合类型JSON数组?aigaming客户端错误处理
解决Go中解析混合类型数组的JSON响应问题
我刚好处理过类似的混合类型JSON解析场景,针对你遇到的stackTrace是混合类型数组的数组这个问题,给你几个实用的解决方案:
方案一:直接用[][]interface{}接收混合数组
这是最直接的方式,因为interface{}可以容纳Go中的任意类型,刚好匹配JSON里的混合元素:
// 定义错误响应结构体 type ErrorResponse struct { Message string `json:"message"` StackTrace [][]interface{} `json:"stackTrace"` // 用二维interface{}数组接收 // 其他返回字段按需添加 }
解析后,你可以通过类型断言来访问数组里的具体值,比如假设每个子数组的第一个元素是函数名字符串,第二个是行号数字:
// 解析响应 var resp ErrorResponse if err := json.Unmarshal(responseBody, &resp); err != nil { // 处理解析错误 log.Fatal(err) } // 遍历stackTrace处理每个帧 for _, frame := range resp.StackTrace { // 断言函数名 if funcName, ok := frame[0].(string); ok { fmt.Printf("调用函数: %s\n", funcName) } // 断言行号(JSON数字默认解析为float64,需要转int) if lineNum, ok := frame[1].(float64); ok { fmt.Printf("行号: %d\n", int(lineNum)) } }
这个方案的优点是快速实现,适合stackTrace结构不固定的场景;缺点是每次访问都要做类型断言,代码稍显繁琐。
方案二:自定义UnmarshalJSON映射到结构化类型
如果stackTrace的子数组元素顺序是固定的(比如每个子数组都是[函数名, 行号, 文件路径]这样的组合),可以自定义解析逻辑,把混合数组映射到更清晰的结构体,后续使用更方便:
// 定义单个栈帧的结构体 type StackFrame struct { FuncName string LineNum int FilePath string } // 错误响应结构体 type ErrorResponse struct { Message string `json:"message"` StackTrace []StackFrame `json:"stackTrace"` // 其他字段... } // 自定义UnmarshalJSON方法,处理混合数组的解析 func (e *ErrorResponse) UnmarshalJSON(data []byte) error { // 先定义临时结构体,用[][]interface{}接收原始stackTrace type TempResp struct { Message string `json:"message"` StackTrace [][]interface{} `json:"stackTrace"` // 其他字段要和ErrorResponse保持一致 } var temp TempResp if err := json.Unmarshal(data, &temp); err != nil { return err } // 把临时的混合数组转换为[]StackFrame frames := make([]StackFrame, len(temp.StackTrace)) for i, arr := range temp.StackTrace { var frame StackFrame // 按顺序断言每个元素,注意处理类型不匹配的情况 if len(arr) >= 1 { frame.FuncName, _ = arr[0].(string) } if len(arr) >= 2 { lineFloat, _ := arr[1].(float64) frame.LineNum = int(lineFloat) } if len(arr) >= 3 { frame.FilePath, _ = arr[2].(string) } frames[i] = frame } // 赋值给最终的ErrorResponse e.Message = temp.Message e.StackTrace = frames // 其他字段同理赋值... return nil }
这样解析后,你可以直接像访问普通结构体字段一样使用resp.StackTrace[i].FuncName,不需要再做类型断言,代码更整洁。
注意事项
- JSON中的数字类型默认会被解析为
float64,如果需要转成int,一定要先做类型断言再转换,避免直接强制转换导致的错误。 - 类型断言时一定要加上
ok判断,防止因为类型不匹配导致panic。 - 如果
stackTrace的子数组元素类型和顺序完全不固定,建议优先用方案一,保持灵活性。
内容的提问来源于stack exchange,提问作者Nikole
相关产品推荐
相关产品推荐

