我想直接导航到地图中的值。让我们更具体地使用以下代码示例,它应该直接给我“Walter”的值:(https://play.golang.org/p/tYJsvp39hn)
type Signature struct{
Name string
Signed bool
}
path := "Document.Signatures.1.Name"
map := map[string]interface{}{
"Document": map[string]interface{}{
"Signatures": []interface{}{
Signature{ Name: "Hugo", Signed: false },
Signature{ Name: "Walter", Signed: false },
},
"Otherstuff": "asadwa",
},
"AlsoOtherStuff": "adwaw",
}
// map.giveMe(path)
// even better (if possible:) map.change(path,"ToThisNewValue")
我已经搜索了解决方案,但我在互联网上找不到任何解决方案。也许你们其中一个人知道怎么做或者知道一个图书馆供我使用。
提前非常感谢你!
答案 0 :(得分:2)
如果没有预定义的结构,将需要很多反射调用。
话虽这么说,你可以通过迭代遍历地图,每次迭代都进行类型检查并相应地处理案例。
// Splitting the path into keys
keys := strings.Split(path, ".")
var value interface{} = map1
for _, key := range keys {
if value, err = Get(key, value); err != nil {
break
}
}
if err == nil {
fmt.Println("Value:", value)
} else {
fmt.Println("Error:", err)
}
func Get(key string, s interface{}) (v interface{}, err error) {
var (
i int64
ok bool
)
switch s.(type) {
case map[string]interface{}:
if v, ok = s.(map[string]interface{})[key]; !ok {
err = fmt.Errorf("Key not present. [Key:%s]", key)
}
case []interface{}:
if i, err = strconv.ParseInt(key, 10, 64); err == nil {
array := s.([]interface{})
if int(i) < len(array) {
v = array[i]
} else {
err = fmt.Errorf("Index out of bounds. [Index:%d] [Array:%v]", i, array)
}
}
case Signature:
r := reflect.ValueOf(s)
v = reflect.Indirect(r).FieldByName(key)
}
//fmt.Println("Value:", v, " Key:", key, "Error:", err)
return v, err
}