Go语言中map[string]int64类型JSON反序列化问题求助
解决Go中JSON字符串数字反序列化为
map[string]int64的问题 我来帮你搞定这个问题!你遇到的核心问题是:json:",string"标签只能作用于结构体的直接字段,没办法影响map内部元素的解析规则,所以当JSON里的value是字符串形式的数字时,没法直接映射到map[string]int64的value上。下面给你两种实用的解决方案:
方案一:自定义结构体的UnmarshalJSON方法
通过给Product实现json.Unmarshaler接口,手动完成字符串到int64的转换,既能保留map[string]int64的类型,又能正确解析JSON:
package main import ( "encoding/json" "fmt" "strconv" ) type Product struct { Count map[string]int64 } // 自定义UnmarshalJSON实现 func (p *Product) UnmarshalJSON(data []byte) error { // 定义临时结构体,先接收字符串类型的map值 type TempProduct struct { Count map[string]string `json:"count"` } var temp TempProduct if err := json.Unmarshal(data, &temp); err != nil { return err } // 把字符串值逐个转换为int64 p.Count = make(map[string]int64, len(temp.Count)) for key, strVal := range temp.Count { intVal, err := strconv.ParseInt(strVal, 10, 64) if err != nil { return fmt.Errorf("解析key %s的数值失败: %w", key, err) } p.Count[key] = intVal } return nil } func main() { s := `{"count":{"FAN":"58"}}` var pro Product err := json.Unmarshal([]byte(s), &pro) if err == nil { fmt.Printf("%+v\n", pro) } else { fmt.Println(err) fmt.Printf("%+v\n", pro) } }
运行这段代码会输出:{Count:map[FAN:58]},完全符合你的需求。
方案二:用json.Number做中间转换
如果不想自定义Unmarshal方法,还可以借助json.Number类型先接收数据,再转换为int64,代码更简洁:
package main import ( "encoding/json" "fmt" ) type Product struct { Count map[string]int64 } func main() { s := `{"count":{"FAN":"58"}}` // 定义临时结构,用json.Number接收字符串数字 var temp struct { Count map[string]json.Number `json:"count"` } if err := json.Unmarshal([]byte(s), &temp); err != nil { fmt.Println(err) return } // 转换为目标结构体的map[string]int64 var pro Product pro.Count = make(map[string]int64, len(temp.Count)) for key, numVal := range temp.Count { intVal, err := numVal.Int64() if err != nil { fmt.Printf("转换key %s的数值失败: %v\n", key, err) return } pro.Count[key] = intVal } fmt.Printf("%+v\n", pro) }
json.Number是Go标准库提供的类型,专门用来处理JSON中字符串形式的数字,调用它的Int64()方法就能安全转换为int64类型。
补充说明:为什么原来的标签没用?
json:",string"标签的设计初衷是:当结构体字段是数字类型时,允许把JSON中的字符串值解析成该数字(比如结构体字段是int64,JSON里是"123")。但这个标签只能作用于结构体的直接字段,无法渗透到map、切片这类复合类型的内部元素上,所以你原来的写法会报错。
内容的提问来源于stack exchange,提问作者Pradip Biswas
相关产品推荐
相关产品推荐

