前言
map 是在 Go 中將值(value)與鍵(key)關聯的內置類型。通過相應的鍵可以獲取到值。
在一個map里所有的鍵都是唯一的,而且必須是支持==和!=操作符的類型,切片、函數以及包含切片的結構類型由於具有引用語義,不能作為映射的鍵,使用這些類型會造成編譯錯誤。
map的value值可以是任意類型,沒有限制。map里所有鍵的數據類型必須是相同的,值也必須如此,但鍵和值的數據類型可以不相同。
注意:map是無序的,我們無法決定它的返回順序,所以,每次打印結果的順序有可能不同。
創建與初始化
package main
import "fmt"
func main() {
//初始化
//1.定義同時初始化
var m1 map[int]string =map[int]string{1:"linlin",2:"sanye"}
fmt.Println(m1)
//2.自動推導類型
m2 := map[int]string{1:"linlin",2:"sanye"}
fmt.Println(m2)
//3.使用make創建
m3 :=make(map[int]string)
fmt.Println(m3)
//創建固定長度的map
m4 := make(map[int]string,10)
fmt.Println(m4)
}
訪問與賦值
package main
import "fmt"
func main() {
//初始化
m2 := map[int]string{1:"linlin",2:"sanye"}
fmt.Println(m2) //map[1:linlin 2:sanye]
m2[1] = "sanye"
m2[2] = "linlin"
fmt.Println(m2) //map[1:sanye 2:linlin]
fmt.Println(m2[1],m2[2])//sanye linlin
}
遍歷
Map的迭代順序是不確定的,並且不同的哈希函數實現可能導致不同的遍歷順序。在實踐中,遍歷的順序是隨機的。每一次遍歷都不相同。
這是故意的,每次都使用隨機的遍歷順序可以強制要求程序不會依賴具體的哈希函數實現。
當使用 for range 遍歷 map 時,不保證每次執行程序獲取的元素順序相同!!!
package main
import "fmt"
func main() {
m3 := map[int]string{0:"linlin",1:"sanye",2:"timi",3:"meyi"}
for k,v := range m3{
fmt.Println("key:%d value:%s",k,v)
}
//判斷map中key是否存在
if v,has :=m3[1];has{ //map[下標]
fmt.Println("value=",v,"has=",has)
} else{
fmt.Println("value=",v,"has=",has)
}
}
刪除
使用delete()函數,指定key值可以方便的刪除map中的k-v映射。
package main
import "fmt"
func mapDelete(m map[int]string,key int) map[int]string{
delete(m,key)
return m
}
func main() {
m3 := map[int]string{0:"linlin",1:"sanye",2:"timi",3:"meyi"}
fmt.Println(m3)//map[0:linlin 1:sanye 2:timi 3:meyi]
delete(m3,1) //刪除key值為2的map
fmt.Println(m3)//map[0:linlin 2:timi 3:meyi]
mapDelete(m3,0)
fmt.Println(m3)//map[2:timi 3:meyi]
}
map為引用類型
map 也是引用類型。當 map 被賦值為一個新變量的時候,它們指向同一個內部數據結構。因此,改變其中一個變量,就會影響到另一變量。
package main
import (
"fmt")
func main() {
personSalary := map[string]int{
"steve": 12000,
"jamie": 15000,
}
personSalary["mike"] = 9000
fmt.Println("Original person salary", personSalary)
newPersonSalary := personSalary
newPersonSalary["mike"] = 18000
fmt.Println("Person salary changed", personSalary)
}
上面程序中的第 14 行,personSalary 被賦值給 newPersonSalary。下一行 ,newPersonSalary 中 mike 的薪資變成了 18000 。personSalary 中 Mike 的薪資也會變成 18000。程序輸出:
Original person salary map[steve:12000 jamie:15000 mike:9000]
Person salary changed map[steve:12000 jamie:15000 mike:18000]
當 map 作為函數參數傳遞時也會發生同樣的情況。函數中對 map 的任何修改,對於外部的調用都是可見的。
map的相等性與長度
map相等性:
map 之間不能使用 == 操作符判斷,== 只能用來檢查 map 是否為 nil。
判斷兩個 map 是否相等的方法是遍歷比較兩個 map 中的每個元素。
map長度:
package main
import (
"fmt")
func main() {
personSalary := map[string]int{
"steve": 12000,
"jamie": 15000,
}
personSalary["mike"] = 9000
fmt.Println("length is", len(personSalary)) //結果為3
}
