在上一篇文章中,我們介紹了兩個線性的資料結構:數組和切片。在本文中,我們會介紹另一種在計算機科學裡常用的資料結構-哈希表(Hash Table)。
哈希表是一種儲存鍵/值對(keuy/value)的資料結構,在哈希表裡,我們會利用一些方法將將鍵映射到物件身上,鍵值之間的連繫關系就是哈希。哈希表有不同的實現方式,但是它們都擁有快速查找、新壞和刪除的特性。Go語言提供了一個內建的map型態。
哈希表的關鍵在於哈希函數的選擇。我們會希望找到一個哈希函數,透過此函數將不同鍵映射到唯一的索引上,
但是這種映射是一種壓縮轉換,也就是輸出的Hash值範圍通常遠小於輸入範圍,不同的蛉入可能會Hash到同一個輸出。因此哈希表在實際使用時,理想狀態是不可能達到的。
兩個不同的輸入值,經過哈希函數計算出同樣的哈希值的現象稱為碰撞。
衡量一個哈希函數的重要指標就是發生碰撞的機率,還有發生碰撞後的解決方案。常見的碰撞解決方案如下:
Go語言裡,宣告map物件的語法如下:
var m map [<KeyType>]ValueType
其中key必須為可以哈希的資料型態,value可以是任何的資料型態,包括map。
Map類似切片,屬於一種reference type,當m宣告後未賦值時,默認值為nil。
將map物件初始化需要用到map函數
//宣告一個m為map型態
var m map [int]int
//將m初始化
m=make(map[int]int)
使用map需要注意的地方
使用delete可以刪除map的元素:
// 初始化一個map物件
support := map[string]float32{"C":3.0, "Go":1.12, "Python":3.7, "Java":10 }
// 查調map有兩個返回,value和ok,當key不存在於map裡時,ok為false,反之ok為true。
version, ok := rating["Java"]
if ok {
fmt.Println("We are supporting the Java %d",version)
} else {
fmt.Println("We are not supporting Java yet")
}
delete(rating, "C") //從map裡頭刪除C的鍵值對
另外map是引用類型,多個變數操作同一個map物件時要小心
m := make(map[string]string)
m["Hello"] = "Bonjour"
m1 := m
m1["Hello"] = "Salut"
fmt.Println(m["Hello"]) //輸出: Salut