JSON解组对象数组时崩溃,原因是空的映射。

huangapple go评论94阅读模式
英文:

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, &amp;aMap)
	*this = make(CustomMap)
	mapToBasicMap(*this, aMap)
	return nil
}

A different fix is to delete method CustomMap.UnmarshalJSON

huangapple
  • 本文由 发表于 2022年10月15日 06:05:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/74075234.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定