Go中自定义Map数组JSON反序列化遇nil map错误如何解决?
Go中自定义Map数组的JSON反序列化问题:assignment to entry in nil map
问题描述
运行以下代码时,在basicMap[key] = value处抛出assignment to entry in nil map异常,但仅当使用[]CustomMap类型时出现该问题——单个CustomMap对象反序列化时可正常运行。如何正确实现自定义对象数组的JSON反序列化?
package main import "encoding/json" type CustomMap map[string]any type Payload struct { Items []CustomMap `json:"items"` } func mapToBasicMap(basicMap CustomMap, aMap map[string]any) { for key, value := range aMap { basicMap[key] = value } } func (this CustomMap) UnmarshalJSON(data []byte) error { var aMap map[string]any = make(map[string]any) json.Unmarshal(data, &aMap) mapToBasicMap(this, aMap) return nil } func main() { payload := Payload{} json.Unmarshal([]byte(`{"items":[{"item1": 1}]}`), &payload) }
问题原因
你的UnmarshalJSON方法使用了值接收者,当反序列化切片中的CustomMap元素时,Go会传递该元素的副本给方法:
- 切片中的原元素是未初始化的nil map;
- 方法内操作的是副本,即使修改副本也不会影响原切片中的元素;
- 直接对nil的副本map执行赋值操作,就会触发
assignment to entry in nil map错误。
解决方案
将UnmarshalJSON的接收者改为指针类型,并在方法内部确保map已初始化后再赋值:
修改后的代码
package main import "encoding/json" type CustomMap map[string]any type Payload struct { Items []CustomMap `json:"items"` } func mapToBasicMap(basicMap CustomMap, aMap map[string]any) { for key, value := range aMap { basicMap[key] = value } } // 改为指针接收者 func (this *CustomMap) UnmarshalJSON(data []byte) error { var aMap map[string]any if err := json.Unmarshal(data, &aMap); err != nil { return err } // 确保map已初始化 if *this == nil { *this = make(CustomMap) } mapToBasicMap(*this, aMap) return nil } func main() { payload := Payload{} err := json.Unmarshal([]byte(`{"items":[{"item1": 1}]}`), &payload) if err != nil { panic(err) } }
关键改动说明
- 指针接收者:
func (this *CustomMap) UnmarshalJSON(...)让方法直接操作原切片中的CustomMap元素,而非副本; - 初始化检查:判断
*this是否为nil,若是则创建新的CustomMap,避免赋值时触发nil map错误; - 错误处理:新增
json.Unmarshal的错误返回,提升代码健壮性。
内容的提问来源于stack exchange,提问作者Zack Newsham
相关产品推荐
相关产品推荐

