go語言map對映
GO語言Map對映
目錄GO語言Map 對映
Map 對映 是一種無序的鍵值對的集合。Map 最重要的一點是通過 key 來快速檢索資料,key 類似於索引,指向資料的值。
Map 是一種集合,所以我們可以像迭代陣列和切片那樣迭代它。不過,Map 是無序的,我們無法決定它的返回順序,這是因為 Map 是使用 hash 表來實現的。
值的型別 | 值的數量 | 值的索引 | |
---|---|---|---|
陣列: | 相同 | 固定 | 下標 |
切片: | 相同 | 動態 | 下標 |
結構體: | 不相同 | 固定 | 屬性名 |
對映: | 相同 | 動態 | key |
對映的實現
因為對映也是一個數據集合,所以,也可以使用類似處理陣列和切片的方式來迭代對映中的元素。但 對映是無序集合,所以即使以同樣的順序儲存鍵值對,每次迭代對映時,元素的順序也可能不一樣。
無序的原因是對映的本質使用了 散列表
map 在底層使用雜湊(hash)來實現的,在C:\Program Files\Go\src\hash\maphash\maphash.go ,map是一個hash陣列列表,由一個個bucket 組成
每一個元素都被稱為bucket的結構體,每一個bucket 可以儲存8個鍵值對,所有元素被hash演算法填入到陣列的bucket中,bucket填滿後,將通過 一個overflow指標來擴充套件一個bucket
定義 Map
可以使用內建函式 make 也可以使用 map 關鍵字來定義 Map:
//使用make 函式,建立一個對映,鍵的型別是string,值的型別是int dict := make(map[string]int) //建立一個對映,鍵值型別都是string,並進行初始化 teacher := map[string]string{"zhangsan":"Chinese","lisi":"English"} //如果僅僅宣告map,而不進行 初始化,那麼就會建立一個空對映,空對映不能存放鍵值對.所以 //方法一: var student map[string]string student = make(map[string]string) //初始化 //方法二: var student map[string]string = map[string]string
如果不初始化 map,那麼就會建立一個 nil map。nil map 不能用來存放鍵值對
對映的 鍵的可以是任何型別內建型別或者結構體都可以,需要確定這個值可以使用 == 運算子做比較。但是如切片,函式,這種引用型別的可以作為對映的鍵
對映的 值 可以是任何型別
元素賦值與獲取元素值
指定適當的型別鍵,並給這個鍵賦一個值就完成了對映的鍵值對賦值
賦值直接定義鍵值對,自動新增。鍵名必須唯一 .如果 鍵名重複,則會修改之前的值
如果想象獲取元素的值,使用鍵名獲取
//賦值
package main
import "fmt"
func main() {
colors := map[string]string{}
colors["red"] = "紅色"
colors["blue"] = "藍色"
fmt.Println(colors)
//鍵名重複,則修改鍵的值
colors["red"] = "紅"
fmt.Println(colors)
}
//輸出結果:
map[blue:藍色 red:紅色]
map[blue:藍色 red:紅]
//通過鍵名,獲取對應的值
package main
import "fmt"
func main() {
colors := map[string]string{}
colors["red"] = "紅色"
colors["blue"] = "藍色"
//使用定義的對映,然後加上下標,下標為鍵名
fmt.Println(colors["red"])
fmt.Println(colors["blue"])
}
//輸出結果:
紅色
藍色
查詢與遍歷、
查詢
從對映去值時,有兩種方式。
第一種方式是:獲得值以及一個表達這個值是否存在的標誌
package main
import "fmt"
func main() {
colors := map[string]string{}
colors["red"] = "紅色"
colors["blue"] = "藍色"
//value 是red 對應的值。 exists 是布林型別,判斷鍵是否存在
value, exists := colors["red"]
fmt.Println(value, exists)
if exists {
fmt.Println("鍵存在")
}
//重新賦值value和exists。
//value 是black 對應的值,如果black不存在,則返回string型別的預設值,即 空
value, exists = colors["black"]
fmt.Println(value, exists)
if !exists {
fmt.Println("鍵不存在")
}
}
紅色 true
鍵存在
false
鍵不存在
//輸出結果:
第二種方式是,只返回鍵對應的值,在判斷這個值是否為0值(int型別),或者是否為空值(string型別)。以此來判斷鍵是否存在。這種方式只能用在對映存的的值都是非0值或者非空值
package main
import "fmt"
func main() {
colors := map[string]string{}
colors["red"] = "紅色"
colors["blue"] = "藍色"
//獲取red 鍵對應的值。如果red鍵不存在,則結果為對應數值型別的預設值。string 型別預設為空
value := colors["red"]
//判斷這個鍵是否存在
if value != "" {
fmt.Println("鍵存在")
fmt.Println(value)
}
}
//輸出結果:
鍵存在
紅色
遍歷
通過使用range 可以迭代對映裡的所有值
package main
import "fmt"
func main() {
colors := map[string]string{}
colors["red"] = "紅色"
colors["blue"] = "藍色"
//使用range 遍歷所有資訊
for key, value := range colors {
fmt.Printf("key:%s,value:%s \n", key, value)
}
}
//輸出結果:
key:red,value:紅色
key:blue,value:藍色
delete函式刪除集合的元素
package main
import "fmt"
func main() {
colors := map[string]string{}
colors["red"] = "紅色"
colors["blue"] = "藍色"
colors["yellow"] = "黃色"
colors["green"] = "綠色"
fmt.Println("刪除前:", colors)
//刪除元素
delete(colors, "red")
fmt.Println("刪除後:", colors)
}
//輸出結果:
刪除前: map[blue:藍色 green:綠色 red:紅色 yellow:黃色]
刪除後: map[blue:藍色 green:綠色 yellow:黃色]
<br<
將對映傳遞給函式
在函式鍵傳遞對映並不會製造出該對映的副本。當傳遞對映給函式並對這個對映做了修改時,所有對這個對映的引用都會察覺到這個修改
package main
import "fmt"
func main() {
colors := map[string]string{}
colors["red"] = "紅色"
colors["blue"] = "藍色"
colors["yellow"] = "黃色"
colors["green"] = "綠色"
fmt.Println("修改前:", colors)
//將對映作為值,傳遞給函式
test(colors)
fmt.Println("修改後:", colors)
}
func test(m map[string]string) {
m["black"] = "黑色"
}
//輸出結果:
修改前: map[blue:藍色 green:綠色 red:紅色 yellow:黃色]
修改後: map[black:黑色 blue:藍色 green:綠色 red:紅色 yellow:黃色]