go語言中map每次遍歷的順序不同-問題分析


WHAT?

發現下面這段代碼,多次運行出的結果是不一樣的

mapper := make(map[int]string)
mapper[1] = "1"
mapper[2] = "2"
mapper[3] = "3"
mapper[4] = "4"
mapper[5] = "5"
mapper[6] = "6"
mapper[7] = "7"


for k, v := range mapper {
    fmt.Println(k, v)
}

  

HOW?

從下面圖片中看到,range獲取迭代器是通過調用了mapiterinit()方法。(圖片來源:https://my.oschina.net/renhc/blog/2396058

 

然后看到mapiterinit方法里,有取隨機數的部分。java語言每次都會按順序去遍歷桶,而go語言會提前取一個隨機數,把桶的遍歷順序隨機化。

(圖片來源:https://blog.csdn.net/u010853261/article/details/99699350

(也可以直接看map源碼。mapiterinit在https://github.com/golang/go/blob/36f30ba289e31df033d100b2adb4eaf557f05a34/src/runtime/map.go 第797行。下圖的這段代碼在827行)

WHY?

遍歷map的時候,每次取隨機數,看起來是沒有意義的,為什么要這樣設計呢?(尋找答案的時候,看到有些博客說go的早期版本的map遍歷沒有取隨機數這個步驟)

(圖片來源:https://blog.csdn.net/slvher/article/details/44779081

讀完上面的內容,我的理解就是:如果沒有設置這個隨機數,那么在大多數情況下,golang會表現出map的順序是固定的情況。但是golang底層並沒有保證這一點,或許(現在/以后)會有特殊情況出現順序不固定的情況。擔心開發者們誤解這一點,golang就特意去打亂了這個順序,讓開發者們知道golang底層不保證map每次遍歷都是同一個順序。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM