我可以使用go语言将json字符串解码为映射,如下所示:
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。我试过很多方法,但都失败了,有人能帮我吗?
我试过这样做:
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
}我也试过这样做:
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
}发布于 2017-09-24 21:35:03
不能直接解组到sync.Map中,因为sync.Map没有导出的字段(因此解组程序没有任何方法在其中存储数据),而且它也没有实现json.Unmarshaler接口。
因此,您必须自己处理这个问题,可能是通过在您自己的类型中包含一个sync.Map,并在该类型上实现json.Unmarshaler:
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
}发布于 2018-02-02 02:51:03
以防您需要用另一种方式来执行此操作
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)
}发布于 2020-12-25 04:12:27
除了@jakub关于MarshalJSON的很好的回答之外,你还可以有一个不检查类型的泛型函数(因为json也不关心)
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函数,您可以通过省略字符串部分来处理一些类型,使其更具泛型(双关语,在角落里哭):
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
}通常,在进行这种操作时使用相同的类型是很好的,因为我们很懒,而且我们不想重写函数;)
https://stackoverflow.com/questions/46390409
复制相似问题