Вложенные карты в Golang

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? Или нет поддержки нескольких скобок для вложенных карт?

1 ответов


на нулевое значение для типов карт составляет nil. Он еще не инициализирован. Вы не можете хранить значения в nil карта, это паника во время выполнения.

в последнем примере вы инициализируете (внешний) data карта, но у нее нет записи. Когда вы индексируете его как data["a"], так как нет записи с "a" ключ в нем еще, индексирование возвращает нулевое значение типа значения, которое является nil для карты. Поэтому попытка назначить 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]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.