出于效率考慮,我們經常使用單個變量來循環叠代器。但在循環中,每次循環叠代中都會有不同的值,有時候會導緻未知的行為。
in := []int{1, 2, 3}
var out []*int
for _, v := range in {
out = append(out, &v)
}
fmt.Println("Values:", *out[0], *out[1], *out[2])
fmt.Println("Addresses:", out[0], out[1], out[2])
輸出
Values: 3 3 3
Addresses: 0xc000014188 0xc000014188 0xc000014188
在out這個slice中的元素都是3。
原因:在每次叠代中,v是單個變量(内存地址不變),所以每次叠代都采用新值将 v append 到 out切片中。
最簡單的解決方法是将循環叠代器變量賦值到新變量中:
in := []int{1, 2, 3}
var out []*int
for _, v := range in {
v := v
out = append(out, &v)
}
fmt.Println("Values:", *out[0], *out[1], *out[2])
fmt.Println("Addresses:", out[0], out[1], out[2])
新的輸出:
Values: 1 2 3
Addresses: 0xc0000b6010 0xc0000b6018 0xc0000b6020
在 goroutine 中使用循環叠代變量也會有相同的問題。
list := []int{1, 2, 3}
for _, v := range list {
go func() {
fmt.Printf("%d ", v)
}()
}
輸出将是:
3 3 3
請注意,如果不使用 goroutine 運行該函數,則代碼将按預期運行。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!