我可以使用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
}
答案 0 :(得分:5)
您不能直接解组为sync.Map
,因为sync.Map
没有导出的字段(因此Unmarshaler没有任何方法可以在其中存储数据),并且它没有实现{ {1}}界面。
所以你必须自己处理这个问题,可能是在你自己的类型中包含json.Unmarshaler
,并在该类型上实现sync.Map
:
json.Unmarshaler
答案 1 :(得分:3)
只需向@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
}
一般来说,在进行这种操作时最好使用相同的类型,因为我们很懒惰,不想重写函数;)
答案 2 :(得分:2)
如果你需要一个代码片段来做另一种方式
export const initializeApp = () => {
return new Promise((resolve, reject) => {
// an "inner" function that creates a closure over resolve
// and which does the check if window.AppApi is set
function checkIfApiLoaded() {
if (window.AppApi) {
console.log('App initialized.');
resolve(true);
} else {
console.log('waiting for App to initialize...');
// if window.AppApi was not set call checkIfApiLoaded with a delay,
// because of the closure it will still know the 'resolve' function
setTimeout(checkIfApiLoaded, 250);
}
}
// initially call this inner function
checkIfApiLoaded()
});