2017-06-01 84 views
6
func main() { 
    var data = map[string]string{} 
    data["a"] = "x" 
    data["b"] = "x" 
    data["c"] = "x" 
    fmt.Println(data) 
} 

它運行。Golang中的嵌套地圖

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有沒有嵌套地圖的問題?或者是否沒有嵌套地圖的多個支架支持?

回答

7

地圖類型的zero valuenil。它尚未初始化。您無法將值存儲在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]] 

注意,當你聲明一個變量的地圖類型並使用composite literal(如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

+0

我意識到我編碼golang與PHP的習慣:)很難習慣於完整的類型安全編碼。但我喜歡它,非常感謝你的答案。 –

+0

在迭代地填充映射的情況下,可以在賦值之前檢查零值:'if data [「c」] == nil {「c」] = map [string] string {}}'這有助於避免丟失地圖中的數據。 – J0hnG4lt