英文:
JSON unmarshalling of array of objects crashes with nil map
问题
我有以下的最小复现代码,当这段代码运行时,在basicMap[key] = value处会抛出一个异常,异常信息是assignment to entry in nil map,然而,只有当类型是[]CustomMap时才会出现这个问题——当我使用CustomMap作为单个项时,它运行得很好。
在Go语言中,有没有一种方法可以解组自定义对象的数组?
package main
import "encoding/json"
type CustomMap map[string]interface{}
type Payload struct {
	Items []CustomMap `json:"items"`
}
func mapToBasicMap(basicMap CustomMap, aMap map[string]interface{}) {
	for key, value := range aMap {
		basicMap[key] = value
	}
}
func (this CustomMap) UnmarshalJSON(data []byte) error {
	var aMap map[string]interface{} = make(map[string]interface{})
	json.Unmarshal(data, &aMap)
	mapToBasicMap(this, aMap)
	return nil
}
func main() {
	payload := Payload{}
	json.Unmarshal([]byte(`{"items":[{"item1": 1}]}`), &payload)
}
英文:
I have the following minimal reproduction, when this code runs it throws an exception at basicMap[key] = value because assignment to entry in nil map, however it only does this when the type is []CustomMap - when I use a CustomMap for a single item, it works just fine.
Is there a way of unmarshalling arrays of custom objects in go?
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)
}
</details>
# 答案1
**得分**: 2
Unmarshal应该具有指针接收器。在使用其值之前,先创建目标映射。
```go
func (this *CustomMap) UnmarshalJSON(data []byte) error {
    var aMap map[string]any = make(map[string]any)
    json.Unmarshal(data, &aMap)
    *this = make(CustomMap)
    mapToBasicMap(*this, aMap)
    return nil
}
另一种修复方法是删除CustomMap.UnmarshalJSON方法。
英文:
Unmarshal should have a pointer receiver. Make the target map before using assigning to its values.
func (this *CustomMap) UnmarshalJSON(data []byte) error {
	var aMap map[string]any = make(map[string]any)
	json.Unmarshal(data, &aMap)
	*this = make(CustomMap)
	mapToBasicMap(*this, aMap)
	return nil
}
A different fix is to delete method CustomMap.UnmarshalJSON
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论