Go語言map實現(xiàn)順序讀取
Go 語言中的 map 是一種非常強大的數(shù)據(jù)結(jié)構(gòu),它允許我們快速地存儲和檢索鍵值對。
然而,當(dāng)我們遍歷 map 時,會有一個有趣的現(xiàn)象,那就是輸出的鍵值對順序是不確定的。
現(xiàn)象
先看一段代碼示例:
package main import "fmt" func main() { ? ? m := map[string]int{ ? ? ? ? "apple": ?1, ? ? ? ? "banana": 2, ? ? ? ? "orange": 3, ? ? } ? ? for k, v := range m { ? ? ? ? fmt.Printf("key=%s, value=%d\n", k, v) ? ? } }
當(dāng)我們多執(zhí)行幾次這段代碼時,就會發(fā)現(xiàn),輸出的順序是不同的。
原因
首先,Go 語言 map 的底層實現(xiàn)是哈希表,在進行插入時,會對 key 進行 hash 運算。這也就導(dǎo)致了數(shù)據(jù)不是按順序存儲的,和遍歷的順序也就會不一致。
第二,map 在擴容后,會發(fā)生 key 的搬遷,原來落在同一個 bucket 中的 key,搬遷后,有些 key 可能就到其他 bucket 了。
而遍歷的過程,就是按順序遍歷 bucket,同時按順序遍歷 bucket 中的 key。
搬遷后,key 的位置發(fā)生了重大的變化,有些 key 被搬走了,有些 key 則原地不動。這樣,遍歷 map 的結(jié)果就不可能按原來的順序了。
最后,也是最有意思的一點。
那如果說我已經(jīng)初始化好了一個 map,并且不對這個 map 做任何操作,也就是不會發(fā)生擴容,那遍歷順序是固定的嗎?
答:也不是。
Go 杜絕了這種做法,主要是擔(dān)心程序員會在開發(fā)過程中依賴穩(wěn)定的遍歷順序,因為這是不對的。
所以在遍歷 map 時,并不是固定地從 0 號 bucket 開始遍歷,每次都是從一個隨機值序號的 bucket 開始遍歷,并且是從這個 bucket 的一個隨機序號的 cell 開始遍歷。
如何順序讀取
如果希望按照特定順序遍歷 map,可以先將鍵或值存儲到切片中,然后對切片進行排序,最后再遍歷切片。
改造一下上面的代碼,讓它按順序輸出:
package main import ( ? ? "fmt" ? ? "sort" ) func main() { ? ? m := map[string]int{ ? ? ? ? "apple": ?1, ? ? ? ? "banana": 2, ? ? ? ? "orange": 3, ? ? } ? ? // 將 map 中的鍵存儲到切片中 ? ? keys := make([]string, 0, len(m)) ? ? for k := range m { ? ? ? ? keys = append(keys, k) ? ? } ? ? // 對切片進行排序 ? ? sort.Strings(keys) ? ? // 按照排序后的順序遍歷 map ? ? for _, k := range keys { ? ? ? ? fmt.Printf("key=%s, value=%d\n", k, m[k]) ? ? } }
在上面的代碼中,首先將 map 中的鍵存儲到一個切片中,然后對切片進行排序。
最后,按照排序后的順序遍歷 map。這樣就可以按照特定順序輸出鍵值對了。
參考文章:
https://golang.design/go-questions/map/unordered/
到此這篇關(guān)于Go語言map實現(xiàn)順序讀取的文章就介紹到這了,更多相關(guān)Go map順序讀取內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang測試func?TestXX(t?*testing.T)的使用詳解
一般Golang中的測試代碼都以xxx_test.go的樣式,在命名測試函數(shù)的時候以Testxx開頭,下面給大家介紹Golang測試func?TestXX(t?*testing.T)的使用,感興趣的朋友跟隨小編一起看看吧2024-08-08go語言使用range來接收通道里面的數(shù)據(jù)
本文主要介紹了go語言使用range來接收通道里面的數(shù)據(jù),for ... range?循環(huán)會一直從通道中接收值,直到通道關(guān)閉并且所有值都被接收完畢,下面就來介紹一下,感興趣的可以了解一下2025-04-04Go語言遍歷map實現(xiàn)(訪問map中的每一個鍵值對)
這篇文章主要介紹了Go語言遍歷map實現(xiàn)(訪問map中的每一個鍵值對),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01Go語言基礎(chǔ)學(xué)習(xí)之?dāng)?shù)組的使用詳解
數(shù)組相必大家都很熟悉,各大語言也都有數(shù)組的身影。Go 語言也提供了數(shù)組類型的數(shù)據(jù)結(jié)構(gòu)。本文就來通過一些簡單的示例帶大家了解一下Go語言中數(shù)組的使用,希望對大家有所幫助2022-12-12golang使用iconv報undefined:XXX的問題處理方案
這篇文章主要介紹了golang使用iconv報undefined:XXX的問題處理方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03GO中的時間操作總結(jié)(time&dateparse)
日常開發(fā)過程中,對于時間的操作可謂是無處不在,但是想實現(xiàn)時間自由還是不簡單的,多種時間格式容易混淆,本文為大家整理了一下GO中的時間操作,有需要的可以參考下2023-09-09golang 實現(xiàn)比特幣內(nèi)核之處理橢圓曲線中的天文數(shù)字
比特幣密碼學(xué)中涉及到的大數(shù)運算超出常規(guī)整數(shù)范圍,需使用golang的big包進行處理,通過使用big.Int類型,能有效避免整數(shù)溢出,并保持邏輯正確性,測試展示了在不同質(zhì)數(shù)模下的運算結(jié)果,驗證了邏輯的準(zhǔn)確性,此外,探討了費馬小定理在有限字段除法運算中的應(yīng)用2024-11-11