func main() { var data = map[string]string{} data["a"] = "x" data["b"] = "x" data["c"] = "x" fmt.Println(data) }
它运行。
func main() { var data = map[string][]string{} data["a"] = append(data["a"], "x") data["b"] = append(data["b"], "x") data["c"] = append(data["c"], "x") fmt.Println(data) }
它也可以运行。
func main() { var w = map[string]string{} var data = map[string]map[string]string{} w["w"] = "x" data["a"] = w data["b"] = w data["c"] = w fmt.Println(data) }
它再次运行!
func main() { var data = map[string]map[string]string{} data["a"]["w"] = "x" data["b"]["w"] = "x" data["c"]["w"] = "x" fmt.Println(data) }
但是失败了!?
Go中的嵌套地图有问题吗?还是对嵌套地图没有多括号支持?
地图类型的零值为nil。尚未初始化。您无法在nil地图中存储值,这是运行时的恐慌。
nil
在上一个示例中,您初始化了(外部)data映射,但是它没有条目。当您像那样对它进行索引时data["a"],由于尚无"a"键输入,因此对其进行索引将返回nil用于地图的值类型的零值。因此,尝试分配给data["a"]["w"]运行时恐慌。
data
data["a"]
"a"
data["a"]["w"]
您必须先初始化地图,然后再在其中存储元素,例如:
var data = map[string]map[string]string{} data["a"] = map[string]string{} data["b"] = make(map[string]string) data["c"] = make(map[string]string) data["a"]["w"] = "x" data["b"]["w"] = "x" data["c"]["w"] = "x" fmt.Println(data)
输出(在Go Playground上尝试):
map[a:map[w:x] b:map[w:x] c:map[w:x]]
请注意,当您声明映射类型的变量并使用复合文字对其进行初始化时(如所述var data = map[string]string{}),这也算作初始化。
var data = map[string]string{}
请注意,您还可以使用复合文字来初始化嵌套地图:
var data = map[string]map[string]string{ "a": map[string]string{}, "b": map[string]string{}, "c": map[string]string{}, } data["a"]["w"] = "x" data["b"]["w"] = "x" data["c"]["w"] = "x" fmt.Println(data)
输出是相同的。在Go Playground上尝试一下。