亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Go 中迭代地圖時修改地圖

在 Go 中迭代地圖時修改地圖

Go
開心每一天1111 2022-09-19 10:41:42
鑒于以下代碼,我預計會出現無限循環,但循環在某個點停止。m := make(map[int]string, 4)m[0] = "Foo"    for k, v := range m {    m[k+1] = v}我無法弄清楚引擎蓋下發生了什么,因為不同的執行返回不同的輸出。例如,這些是來自不同執行的幾個輸出:map[0:Foo 1:Foo 2:Foo 3:Foo 4:Foo 5:Foo 6:Foo 7:Foo]map[0:Foo 1:Foo]map[0:Foo 1:Foo 2:Foo]如何工作才能在特定點退出循環,退出條件是什么?range
查看完整描述

3 回答

?
蝴蝶刀刀

TA貢獻1801條經驗 獲得超8個贊

Spec:對于具有范圍子句的語句,表示行為是不可預測的:

未指定映射的迭代順序,也不保證從一次迭代到下一次迭代相同。如果在迭代期間移除尚未到達的映射條目,則不會生成相應的迭代值。如果在迭代期間創建了映射條目,則該條目可能會在迭代期間生成,也可以跳過。對于創建的每個條目以及從一次迭代到下一次迭代,選擇可能會有所不同。如果映射為 ,則迭代次數為 0。nil

將元素添加到您正在測距的地圖中,這些條目可能會被循環訪問,也可能不會被循環訪問,您不應該假設與此相關的任何事情。


查看完整回答
反對 回復 2022-09-19
?
明月笑刀無情

TA貢獻1828條經驗 獲得超4個贊

其他答案已經解釋了您在代碼段中觀察到的行為。


由于您的標題相當通用,但您的代碼段僅涵蓋在迭代地圖時添加地圖條目,因此這里有一個補充示例,應該說服您,在迭代地圖時“交叉刪除”地圖條目是一個壞主意(Playground):


package main


import "fmt"


func main() {

    m := map[string]int{"foo": 0, "bar": 1, "baz": 2}

    for k := range m {

        if k == "foo" {

            delete(m, "bar")

        }

        if k == "bar" {

            delete(m, "foo")

        }

    }

    fmt.Println(m)

}

該規范說:


未指定映射的迭代順序,也不保證從一次迭代到下一次迭代相同。如果在迭代期間移除尚未到達的映射條目,則不會生成相應的迭代值。


結果,程序輸出 或 ,但無法分辨哪個。map[bar:1 baz:2]map[baz:2 foo:0]


查看完整回答
反對 回復 2022-09-19
?
MMTTMM

TA貢獻1869條經驗 獲得超4個贊

基于語言規范:

如果在迭代期間創建了映射條目,則該條目可能會在迭代期間生成,也可以跳過。

因此,如果跳過新元素,for 循環最終會結束。


查看完整回答
反對 回復 2022-09-19
  • 3 回答
  • 0 關注
  • 122 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號