I can decode json strings to a map with go language like this:
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))
}
}
but I wonder how to decode it to a sync.Map in Go1.9. I have tried many ways but failed, can anyone help me?
I tried like this:
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
}
Also I tried like this:
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
}
You cannot directly unmarshal into a sync.Map
, because sync.Map
has no exported fields (so the Unmarshaler doesn't have any way to store data in it), and it doesn't implement the json.Unmarshaler
interface.
So you'll have to handle this yourself, probably by including a sync.Map
in a type of your own, and implementing json.Unmarshaler
on that type:
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
}
In case you need a snippet to do it another way around
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)
}