[Go]字典(map)的操作和約束
字典(map)存儲的是鍵值對(key-value pair,一個鍵值對代表了一對鍵和值。一個鍵和一個值分別代表了一個從屬於某一類型的獨立值,把它們兩個捆綁在一起就是鍵值對,也稱“鍵-元素對”)的集合
Go語言的字典類型其是由一個哈希表特定實現的,在這個實現中,鍵和元素最大不同在於,前者的類型是受限的,後者卻可以是任何類型
1 package main 2 3 import ( 4 "fmt" 5 ) 6 7 func main() { 8 aMap := map[string]int{ 9 "one": 1, 10 "two": 2, 11 "three": 3, 12 } 13 k := "two" 14 v, ok := aMap[k] 15 if ok{ 16 fmt.Printf("THe element of key %q: %d\n", k, v) 17 }else { 18 fmt.Println("Not found!") 19 } 20 }
在哈希表中查找某個鍵值對應的那個元素值,需要先把鍵值作為參數傳給這個哈希表,哈希表會先用哈希函數把鍵值轉換為哈希值。哈希值通常是一個無符號的整數,一個哈希表會持有一定數量的桶(bucket,哈希桶),這些哈希桶會均勻地存儲其所屬哈希表收納的那些鍵值對。哈希表會先用這個鍵的哈希值的低幾位去定位到一個哈希桶,然後再到這個哈希桶中查找這個鍵,由於鍵值對是捆綁在一起存儲的,所以一旦找到了鍵,就一定能找到對應的元素值。隨後哈希表就會把相應的元素值作為結果返回
1、字典的鍵類型不能是哪些類型?
Go語言規範規定,在鍵類型的值之間必須可以施加操作符==和!=,即鍵類型的值必須要支持判等操作。由於函數類型、字典類型、切片類型不支持判等操作,所以字典的鍵類型不能是這些類型。
不建議使用高級數據類型(數組、接口、結構體)作為字典的鍵類型,它們的值求哈希較慢,並且它們的值中存在變數(可以修改其中的元素值),還需要對其內部元素類型進行判斷
如鍵的類型是數組類型,那麽還要確保該類型的元素類型不是函數類型、字典類型或切片類型
2、應該優先考慮哪些類型作為字典的鍵類型?
求哈希和判等操作的速度越快,對應的類型就越適合作為鍵類型
寬度(單個值需要占用的字節數,如bool、int8的字節寬度都是1)越小的類型速度通常越快。對高級類型,如數組類型的值求哈希實際上是依次求得它的每個元素的哈希值並進行合並
因此優先選用數值類型和指針類型作為字典的鍵類型
3、在值為nil的字典上執行讀操作會成功嗎?那寫操作呢?
由於字典是引用類型,所以當我們僅聲明而不初始化一個字典類型的變量的時候,它的值會是nil
除添加鍵值對,在一個值為nil的字典上做任何操作都不會引起錯誤。當試圖在一個值為nil的字典中添加鍵值對時,會拋出panic
[Go]字典(map)的操作和約束