Golang中如何将含string与float64的JSON解码为二维切片?
解决JSON混合string/float64类型的解码问题
嘿,这个场景我太熟悉了——数据库返回的JSON里字段类型不统一,既有字符串又有数字,直接解码成固定类型的二维切片肯定会炸。手动修改JSON字符串虽然能凑合用,但确实不够优雅,咱们完全可以通过代码层面的类型处理来解决,给你两个实用的方案:
方案一:自定义类型实现UnmarshalJSON(推荐长期复用)
核心思路是定义一个能兼容string和float64的自定义类型,然后实现Go的json.Unmarshaler接口,让它自动处理类型转换。
比如咱们定义一个MixedField类型:
import ( "encoding/json" "strconv" ) type MixedField string func (mf *MixedField) UnmarshalJSON(data []byte) error { // 先尝试解析成字符串 var s string if err := json.Unmarshal(data, &s); err == nil { *mf = MixedField(s) return nil } // 字符串解析失败,尝试解析成数字再转字符串 var f float64 if err := json.Unmarshal(data, &f); err != nil { return err } // 这里可以根据需求处理数字格式,比如去掉末尾的.0 *mf = MixedField(strconv.FormatFloat(f, 'f', -1, 64)) return nil }
之后你就可以直接把目标类型定义成[][]MixedField来解码了:
var result [][]MixedField err := json.Unmarshal(jsonData, &result) if err != nil { // 处理错误 } // 后续使用时可以转成string:string(result[i][j])
这个方案的好处是代码复用性强,逻辑封装在自定义类型里,后续再碰到类似的混合类型JSON直接用这个类型就行。
方案二:先用interface{}接收再转换(适合临时快速处理)
如果只是一次性的需求,不想定义新类型,可以先把JSON解码成[][]interface{},然后遍历转换每个元素:
import ( "encoding/json" "fmt" "strconv" ) var rawResult [][]interface{} err := json.Unmarshal(jsonData, &rawResult) if err != nil { // 处理错误 } // 转换为[][]string finalResult := make([][]string, len(rawResult)) for i, row := range rawResult { finalResult[i] = make([]string, len(row)) for j, val := range row { switch v := val.(type) { case string: finalResult[i][j] = v case float64: // 同样可以按需处理数字格式 finalResult[i][j] = strconv.FormatFloat(v, 'f', -1, 64) default: // 处理其他意外类型,比如bool、null等 finalResult[i][j] = fmt.Sprintf("%v", v) } } }
这个方案更灵活,但代码相对零散,适合临时处理简单场景。
额外小建议
如果能控制数据库查询语句的话,最好在查询阶段就把所有需要的字段强制转成字符串类型(比如SQL里用CAST(column AS VARCHAR)),从根源上避免类型混合的问题,这才是最省心的办法。
内容的提问来源于stack exchange,提问作者Raed
相关产品推荐
相关产品推荐

