2 回答

TA貢獻(xiàn)1862條經(jīng)驗(yàn) 獲得超7個(gè)贊
方法 1 中的問題是您沒有獲取字符串的地址,而是獲取了它所在變量的地址。在 Go 中,&v返回變量的地址v。當(dāng)你有這樣的循環(huán)時(shí):
for k, v := range aMap {
...
}
您在循環(huán)開始時(shí)聲明的變量k和v在整個(gè)循環(huán)中使用的變量是相同的。它們只是在每次迭代中被分配了不同的值。在該循環(huán)中,&v總是計(jì)算出相同的值: 的地址v。這就是為什么您的所有地圖條目都出現(xiàn)在"foo":"foo"中的最后一個(gè)值v,并且它仍然存在。
您可以通過更改字符串值來查看此行為。所有的地圖鍵都會(huì)改變:
*bMap["foo"] = "quux"
fmt.Println(*bMap["bar"]) // prints "quux"
方法 2 有效,因?yàn)楹瘮?shù)的每次調(diào)用都有自己的局部變量。Go 保證,如果您從函數(shù)返回局部變量的地址,該變量將被分配在堆上,只要需要它就可以使用它。所以你的輔助函數(shù)告訴 Go 分配一個(gè)新string變量,將傳入的字符串復(fù)制到它,然后返回它的地址。
這是另一種可行的方法:
dMap := make(map[string]*string)
for k, v := range(aMap){
dMap[k] = new(string)
*dMap[k] = v
}
這會(huì)分配一個(gè)新的字符串變量,將其地址保存在映射中,然后將 v 復(fù)制到其中。如果您要經(jīng)常這樣做,輔助函數(shù)可能是最好的。
您嘗試的代碼如下:
v := "foo"
val := *v
bMap[key] = &val
不起作用,因?yàn)槟f“v 是一個(gè)字符串;現(xiàn)在將字符串指向的值存儲(chǔ)在 val 中”,但該字符串不是指針。

TA貢獻(xiàn)1854條經(jīng)驗(yàn) 獲得超8個(gè)贊
問題中的第一種方法使用v所有鍵的單個(gè)循環(huán)變量的地址。您看到的值是最后一個(gè)設(shè)置為 的值v。
通過為每次迭代聲明一個(gè)新變量并獲取該變量的地址來修復(fù)。
bMap := make(map[string]*string)
for k, v := range aMap {
v := v // declare new variable v initialized with value from outer v
bMap[k] = &v
}
問題中的第二種方法還為循環(huán)中的每次迭代聲明了一個(gè)新變量。新變量是函數(shù)參數(shù)。
這個(gè)答案顯示了解決這個(gè)問題的慣用方法。請(qǐng)參閱Go 常見問題解答:作為 goroutine 運(yùn)行的閉包會(huì)發(fā)生什么?在閉包和 goroutine 的上下文中討論相同的問題。
- 2 回答
- 0 關(guān)注
- 144 瀏覽
添加回答
舉報(bào)