如何在Golang中向地图映射中添加数据?

20

我正在学习使用映射图。在下面的例子中,有三个嵌套的映射。

package main

import (
    "fmt"
)

func main() {

    var data = map[string]map[string]map[string]string{}

    data["Date_1"] = map[string]map[string]string{}
    data["Date_1"] = make(map[string]map[string]string, 1)
    data["Date_1"] = make(map[string]map[string]string, 0)

    data["Date_1"]["Sistem_A"] = map[string]string{}
    data["Date_1"]["Sistem_A"] = make(map[string]string, 0)
    data["Date_1"]["Sistem_A"] = make(map[string]string, 0)

    data["Date_1"]["Sistem_A"]["command_1"] = "white"
    data["Date_1"]["Sistem_A"]["command_2"] = "blue"
    data["Date_1"]["Sistem_A"]["command_3"] = "red"

    fmt.Println("data: ", data)
}

输出

data:  map[Date_1:map[Sistem_A:map[command_1:white command_2:blue command_3:red]]]

问题在于,如果我想一步添加值,会出现panic:assignment to entry in nil map。

package main

import (
    "fmt"
)

func main() {

    var data = map[string]map[string]map[string]string{}

    data["Date_1"] = map[string]map[string]string{}
    data["Date_1"] = make(map[string]map[string]string, 0)
    data["Date_1"] = make(map[string]map[string]string, 0)

    data["Date_1"]["Sistem_A"] = map[string]string{}
    data["Date_1"]["Sistem_A"] = make(map[string]string, 0)
    data["Date_1"]["Sistem_A"] = make(map[string]string, 0)

    data["Date_1"]["Sistem_A"]["command_1"] = "white"
    data["Date_1"]["Sistem_A"]["command_2"] = "blue"
    data["Date_1"]["Sistem_A"]["command_3"] = "red"

    data["Date_2"]["Sistem_A"]["command_5"] = "violet"

    fmt.Println("data: ", data)
}

输出

panic: assignment to entry in nil map

此时,指导信息非常有限。你能帮助我吗?

谢谢。

2个回答

27

这是它的位置:

    data["Date_2"]["Sistem_A"]["command_5"] = "violet"

data["Date_2"]表达式将返回一个空映射。它从未被初始化,因此查找索引["Sistem_A"]将会导致程序崩溃。请先初始化该映射:

    data["Date_2"] = make(map[string]map[string]string)
    data["Date_2"]["Sistem_A"] = make(map[string]string)
    data["Date_2"]["Sistem_A"]["command_5"] = "violet"

非常感谢。要在三个组合的For-Ranges方案中实现此类地图(其中地图将获取其值),我应该在循环中初始化这些地图吗?还是有一种方法可以在For-Range之前进行(不知道将添加多少数据)? - Jumanyi
1
在对map进行设置/获取值之前,您必须确保它已初始化。您可以懒惰地初始化它,或者您可以编写一个for循环来初始化所有内容。如果您知道在所有级别上需要的键,则使用for循环初始化更易读。 - Burak Serdar
@Burak Serdar - 只是一个小细节:您不能向nil映射添加内容,但可以从nil映射中读取(获取),在这种情况下,将返回映射元素的默认类型(如果使用第二个返回值,则为false,表示该元素不存在)。 - AJR
@BurakSerdar 我有以下问题。我提出的案例会生成恐慌,因为地图没有初始化。但在这个例子中,我看到地图不是空的。 var data = map [string] map [string] map [string] string {} if data == nil { fmt.Println ("data is nil") } else { fmt.Println ("data is not nil") } 产量 数据不为空 问题在嵌套地图中吗? 这些是没有初始化的吗? - Jumanyi
地图data已初始化。地图data["someitem"]未初始化。 - Burak Serdar

2

你的问题在于,你从未初始化data["Date_2"](因此它是nil)。

因此通过执行data["Date_2"]["Sistem_A"]["command_5"] = "violet",查找索引会导致崩溃。

你需要先进行初始化,如下所示:

data["Date_2"]=make(map[string]map[string]string)
data["Date_2"]["Sistem_A"]=make(map[string]string)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接