Map 解组成地图

Map 解组成地图,map,go,unmarshalling,Map,Go,Unmarshalling,如何将数据解组到地图中 JSON是一个对象列表,我想在解组期间将其转换为一个映射。但是,初始化映射似乎会创建一个未正确返回的新对象 type foo struct { Id string `json:"id"` Name string `json:"name"` } type fooList []*foo type fooMap map[string]*foo func (f fooMap) UnmarshalJSON(data []byte) error { f :

如何将数据解组到地图中

JSON是一个对象列表,我想在解组期间将其转换为一个映射。但是,初始化映射似乎会创建一个未正确返回的新对象

type foo struct {
    Id string `json:"id"`
    Name string `json:"name"`
}

type fooList []*foo
type fooMap map[string]*foo

func (f fooMap) UnmarshalJSON(data []byte) error {
    f := fooMap{} // required since map is not initialized

    var results fooList
    if err := json.Unmarshal(data, &results); err != nil {
        return err
    }

    for i := 0; i < len(results); i++ {
        result := results[i]
        f[result.Id] = result
    }

    return nil
}

我还尝试将
Foos
更改为
*fooMap
类型,然后将unmarshal函数更新为
func(f*fooMap)UnmarshalJSON(…)
,但此后从未调用unmarshal函数。

这似乎过于复杂,这里有几个令人困惑的部分

  • 在解组过程中,您真的需要中间愚人吗?这使得json表示看起来与您定义的类型不同,这让我一开始感到困惑
  • 至少在这里,没有理由为所有内容定义自己的类型,这使得代码很难阅读,因为它将结构隐藏在另一层间接寻址之后
因此,问题的关键在于fooMap方法没有指针接收器。这使得不可能从方法中为接收器分配非nil映射。您确实需要一个指针接收器,您需要在每个索引操作上取消引用它。在代码中,您只是将map数据结构分配给接收方的临时副本(我可能会添加一种无效的方式)

func(f*fooMap)解组JSON(数据[]字节)错误{
*f=make(map[string]*foo)//由于映射未初始化,因此是必需的
var结果傻瓜
如果err:=json.Unmarshal(数据和结果);err!=nil{
返回错误
}
对于i:=0;i

根据我对您的json的最佳猜测:

您也需要发布一些json。最好做一个工作的例子,说明问题的欣赏!我没有意识到Go会使用指针接收器自动查找解组。这就是为什么我在最初的尝试中将struct更改为使用
*fooMap
,但没有成功的原因。这让我感到困惑。
type bar struct {
    Foos fooMap `json:"foos"`
}

type bars []*bar

...

var results bars
if err := json.Unmarshal(data, &results); err != nil {
    return err
}

// here results contains a single bar item (which is correct) but the Foos
// property does not exist at all
func (f *fooMap) UnmarshalJSON(data []byte) error {
    *f = make(map[string]*foo) // required since map is not initialized

    var results fooList
    if err := json.Unmarshal(data, &results); err != nil {
        return err
    }

    for i := 0; i < len(results); i++ {
        result := results[i]
        (*f)[result.Id] = result
    }

    return nil
}