首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将json字符串解码为sync.Map,而不是Go1.9中的normal map?

如何将json字符串解码为sync.Map,而不是Go1.9中的normal map?
EN

Stack Overflow用户
提问于 2017-09-24 21:12:43
回答 3查看 2K关注 0票数 5

我可以使用go语言将json字符串解码为映射,如下所示:

代码语言:javascript
复制
func main(){
  date := []byte(`{"127.1":{"host":"host1","list":["list123","list456"]},"127.2":{"host":"host2","list":["list223","list256"]}}`)
  var x interface{}
  json.Unmarshal(date, &x)
  t := x.(map[string]interface{})
  var aa []interface{}
  aa = (t["127.2"].(map[string]interface{})["list"])
  for _, v := range aa {
     fmt.Println(v.(string))
  }
}

但我想知道如何在Go1.9中将其解码为sync.Map。我试过很多方法,但都失败了,有人能帮我吗?

我试过这样做:

代码语言:javascript
复制
    func main(){
      date := []byte(`{"127.1":{"host":"host1","list":["list123","list456"]},"127.2":{"host":"host2","list":["list223","list256"]}}`)
      var x interface{}
      json.Unmarshal(date, &x)
      t := x.((sync.Map)[string]interface{})  //compile error
}

我也试过这样做:

代码语言:javascript
复制
    func main(){
      date := []byte(`{"127.1":{"host":"host1","list":["list123","list456"]},"127.2":{"host":"host2","list":["list223","list256"]}}`)
      var x sync.Map
      json.Unmarshal(date, &x)
      fmt.Println(x) // but the map has nothing
}
EN

回答 3

Stack Overflow用户

发布于 2017-09-24 21:35:03

不能直接解组到sync.Map中,因为sync.Map没有导出的字段(因此解组程序没有任何方法在其中存储数据),而且它也没有实现json.Unmarshaler接口。

因此,您必须自己处理这个问题,可能是通过在您自己的类型中包含一个sync.Map,并在该类型上实现json.Unmarshaler

代码语言:javascript
复制
type Foo struct {
    sync.Map
}

func (f *Foo) UnmarshalJSON(data []byte) error {
    var tmpMap map[string]interface{}
    if err := json.Unmarshal(data, &tmpMap); err != nil {
        return err
    }
    for key, value := range tmpMap {
        f.Store(key, value)
    }
    return nil
}
票数 8
EN

Stack Overflow用户

发布于 2018-02-02 02:51:03

以防您需要用另一种方式来执行此操作

代码语言:javascript
复制
func (f Foo) MarshalJSON() ([]byte, error) {
    tmpMap := make(map[YourTypeOfKey]YourTypeOfValue)
    f.Range(func(k, v interface{}) bool {
        tmpMap[k.(YourTypeOfKey)] = v.(YourTypeOfValue)
        return true
    })
    return json.Marshal(tmpMap)
}
票数 8
EN

Stack Overflow用户

发布于 2020-12-25 04:12:27

除了@jakub关于MarshalJSON的很好的回答之外,你还可以有一个不检查类型的泛型函数(因为json也不关心)

代码语言:javascript
复制
func MarshalJSON(m *sync.Map) ([]byte, error) {
    tmpMap := make(map[interface{}]interface{})
    m.Range(func(k, v interface{}) bool {
        tmpMap[k] = v
        return true
    })
    return json.Marshal(tmpMap)
}

这可能需要任何类型的sync.Map并对其进行编组。

要添加到@Flimzy的答案中的UnMarshal函数,您可以通过省略字符串部分来处理一些类型,使其更具泛型(双关语,在角落里哭):

代码语言:javascript
复制
func UnmarshalJSON(data []byte) (*sync.Map, error) {
    var tmpMap map[interface{}]interface{}
    m := &sync.Map{}

    if err := json.Unmarshal(data, &tmpMap); err != nil {
        return m, err
    }

    for key, value := range tmpMap {
        m.Store(key, value)
    }
    return m, nil
}

通常,在进行这种操作时使用相同的类型是很好的,因为我们很懒,而且我们不想重写函数;)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46390409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档