在剛剛接觸go語言的時候,就看到很多地方出現了map
。就對這個map
很困惑,那麼這個map
究竟是什麼呢。讓我們一起來看一看吧。
map (映射)是一個種數據結構,用於存儲一些無序的鍵值對。映射使用了兩個數據結構來存儲數據。第一個數據結構是數組,內部存儲的是用戶選擇桶的散列值。第二個數據結構是一個字節數組,用於存儲鍵值對。映射是一個存儲鍵值對的無序集合。
創建和初始化
go語言中可以使用make函數,也可以使用使用字面量的方法來創建映射(map)。如下所示
//通過make函數 創建一個映射,鍵類型是string ,值是int
list := make(map[string]int)
list["test"]= 1
fmt.Println(list["test"])
//創建一個映射,鍵值都是string 使用字面量
data := map[string]string{"top":"is top","bottom":"is bottom"}
fmt.Println(data["top"])
創建映射更常用的方法應該是使用字面量,映射的初始長度會根據初始化時指定的鍵值對數量來確定,映射的鍵可以是任何值,這個值可以是內置類型,也可以是結構類型,只要這個值可以用==運算符比較。需要注意是:切片,函數以及包含切片的結構不能做爲映射的鍵。
映射的使用
賦值
//通過make函數 創建一個映射,鍵類型是string ,值是int
list := make(map[string]int)
//將test的值加入映射
list["test"]= 1
可以通過什麼一個未初始化的映射來創建一個nil
映射,nil
映射不能用於儲存鍵值對
var numbers map[int]int
numbers[1]=1 //這裏會產生一個錯誤
判斷鍵是否存在於映射以及取值
判斷某個鍵是否存在於映射中是一個經常使用的操作。從映射中取值時有兩個方式。第一個是,同時獲取值,以及一個表示鍵是否存在的標誌
data := map[string]string{"top":"is top","bottom":"is bottom"}
val,exists := data["top"]
//如果這個鍵存在
if exists {
fmt.Println(val)
} else {
fmt.Println("top 不存在")
}
第二個方式是,只獲取鍵對應的值,通過這個值是否是零值來判斷是否存在。但是如果這個鍵對應的剛好是零值,那麼這個判斷就會不準確
data := map[string]string{"top":"is top","bottom":""}
v := data["bottom"]
if v!="" {
fmt.Println(v)
}else {
fmt.Println("bottom 不存在")
}
v2 := data["left"]
if v2!="" {
fmt.Println(v2)
}else {
fmt.Println("left 不存在")
}
以上代碼會得到
bottom 不存在
left 不存在
但實際上映射中是存在鍵bottom
的
映射的迭代和數組、切片的迭代一樣,使用range關鍵字
data := map[string]string{"top":"is top","bottom":"is bottom","left":"is left","right":"is right"}
for k,v := range data{
fmt.Printf("k:%s v:%s\n",k,v)
}
需要注意的是,因爲映射是一個無序集合。所以每次迭代得到的鍵值對順序是不一樣的。
刪除映射中的某一個項,使用內置函數delete
data := map[string]string{"top":"is top","bottom":"is bottom","left":"is left","right":"is right"}
delete(data,"top")
映射的傳遞(引用類型)
在函數間傳遞映射並不會製造出該映射的一個副本。實際上,當傳遞映射給一個函數,並對
這個映射做了修改時,所有對這個映射的引用都會察覺到這個修改。
func main() {
m := map[int]int{
0:0,
1:1,
2:2,
3:3,
}
fmt.Println(m)
changeMap(m)
fmt.Println(m)
delMap(m)
fmt.Println(m)
}
func changeMap(m map[int]int) {
m[1]=111
}
func delMap(m map[int]int) {
delete(m,1)
}
上面示例將會輸出
map[0:0 1:1 2:2 3:3]
map[0:0 1:111 2:2 3:3]
map[0:0 2:2 3:3]
可以看到在changeMap
中改變了map
的值或者delMap
中刪除了某一直鍵值對,main
中的值也改變了。這個特性和切片類似,保證可以用很小的成本來複制映射。