<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
和許多程式語言一樣,在 Go 中,字典是一組鍵-值對( Go 中稱鍵-元素對)的集合。
當我們要儲存或者查詢某個鍵-元素對的時候,雜湊表會先使用雜湊函數將鍵值轉換為雜湊值,雜湊值一般是一個無符號的整數。
一個雜湊表內會存有一定數量的雜湊桶,在字典的結構裡面,有一個屬性 B ,這個屬性代表當前字典裡面桶的個數 (2^B) 。
// A header for a Go map. type hmap struct { // Note: the format of the hmap is also encoded in cmd/compile/internal/gc/reflect.go. // Make sure this stays in sync with the compiler's definition. count int // # live cells == size of map. Must be first (used by len() builtin) flags uint8 B uint8 // log_2 of # of buckets (can hold up to loadFactor * 2^B items) noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details hash0 uint32 // hash seed buckets unsafe.Pointer // array of 2^B Buckets. may be nil if count==0. oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing nevacuate uintptr // progress counter for evacuation (buckets less than this have been evacuated) extra *mapextra // optional fields }
比如當 B 為 5 的時候,通過獲取雜湊值的低 5 位就能判斷出當前鍵-元素對應該存放在哪一個桶裡面。例如我們通過雜湊函數,獲取到了一個鍵-元素對中鍵值的雜湊值為
1001011100001111011011001000111100101010001001011001010101011011
其中,低 5 位代表其所屬的桶的位置,11011 換算為十進位制為 26 ,即該鍵-元素對存在第 26 個桶內。雜湊桶記憶體儲的是“鍵的雜湊值-內部結構”對的集合,即是按照 鍵1 鍵2 … 鍵8 元素1 元素2 … 元素8 溢位指標 的方式儲存,是一塊連續的記憶體,且鍵和元素時捆綁儲存的。我們找到雜湊桶之後,再對比鍵值,就可以定位我們所以需要的鍵的位置,又因為鍵 - 元素對是捆綁儲存的,所以找到了鍵就等於是找到對應的元素值。
儲存時也是同樣的道理,但是要注意的是,每一個儲存桶最多隻能儲存 8 個鍵-元素對,當超出 8 個的時候,就會生成一個溢位桶,並且當前雜湊桶的溢位指標(上述連續記憶體的最後一塊)會指向新生成的溢位桶。
其實從上面就可以看出,字典型別其實是一個雜湊表的一個特定實現,其中鍵和元素的最大區別在於鍵必須是可以雜湊的,而元素卻可以是任意型別的,因此字典中的鍵型別是受限的。
// 宣告字典 是個 nil 未初始化,直接存值會報錯 var s0 map[string] int // 宣告字典並初始化 s1 := map[string]int{} // 使用 make 宣告 s2 := make(map[string] int) fmt.Println(s0, s1, s2, s3)
-------結果-------------------------
map[] map[] map[]
要注意:宣告字典的時候 key 的型別不能是函數、字典、切片。因為根據上面查詢字典鍵-元素對的過程可以知道,最後是要通過比較桶內鍵和要查詢的鍵是不是一樣來確定鍵-元素對的位置的,但是這三種型別不支援判等操作,所以鍵的型別不支援這三種,編譯器會直接報錯。
但是有一個比較特殊的型別:介面 interface{},interface{} 是支援判等操作的,所以編譯器不會報錯。但是又因為 interface{} 這個空介面相當於是個萬能型別,可以接受任何型別的值,所以會出現以下情況的程式碼:
var s4 = map[interface{}]int{ "1": 1, []int{2}: 2, 3: 3, } fmt.Println(s4)
------結果--------------
panic: runtime error: hash of unhashable type []int
當我們執行時,就會出現 panic 恐慌。程式執行出現這樣的報錯我們還能及時調整,但在程式執行時,我們新增了這樣的鍵值對進去導致系統異常,再修改就為時已晚了,所以我們最好不要使用 interface{} 作為鍵的型別,而且我們要優先考慮計算雜湊值比較快的型別作為字典的鍵型別 。
//初始化 s0 := map[string]int{} fmt.Println(s0) //新增key-value s0["one"] = 1 s0["two"] = 2 fmt.Println(s0) //修改指定key的值 s0["one"] = 11 s0["two"] = 22 fmt.Println(s0) //刪除指定key的元素 delete(s0, "one") fmt.Println(s0) //獲取key-value對個數 fmt.Println(len(s0))
------結果-------------------
map[]
map[one:1 two:2]
map[one:11 two:22]
map[two:22]
1
如果值的型別是陣列或者結構體,那麼不能直接修改 value 成員
s0 := map[string]struct { x int }{} s0["one"] = struct{ x int }{1} s0["two"] = struct{ x int }{2} s0["one"].x = 1 //這裡編譯器會直接報錯
方法一:先獲取全部value,修改之後重新賦值
s0 := map[string]struct { x int }{} s0["one"] = struct{ x int }{1} s0["two"] = struct{ x int }{2} s0["one"].x = 1 //這裡編譯器會直接報錯 // 正確做法一 s1 := s0["one"] s1.x = 111 s0["one"] = s1 fmt.Println(s0)
-----結果------------------
map[one:{111} two:{2}]
方法二:使用指標型別
* 開頭表示是指標型別
& 是取址符號,即獲取對應程式實體物件的地址
// 正確做法二 // value 的型別是指標型別,指標指向結構體 s0 := map[string]*struct { x int }{} //建立一個結構體並把指標新增到字典中 s0["one"] = &struct{ x int }{1} fmt.Println(*s0["one"]) s0["one"].x = 111 fmt.Println(*s0["one"])
-----結果------------------
{1}
{111}
s0 := map[string]int{} s0["one"] = 1 s0["two"] = 2 //接收 key 和 value for k, vla := range s0 { fmt.Printf("%s:%dn", k, vla) } fmt.Println("-----分割線---------------") //只接收key for k := range s0 { fmt.Printf("%s:%dn", k, s0[k]) }
-----結果----------------
one:1
two:2
-----分割線---------------
one:1
two:2
到此這篇關於Go字典使用詳解的文章就介紹到這了,更多相關Go字典內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45