2 回答

TA貢獻1770條經驗 獲得超3個贊
簡而言之,警告意味著您正在獲取循環變量的地址。
發生這種情況是因為在for語句中重復使用了迭代變量。在每次迭代中,將范圍表達式中下一個元素的值賦給迭代變量;v不會改變,只會改變它的值。因此,該表達式&v指的是內存中的同一位置。
以下代碼四次打印相同的內存地址:
for _, n := range []int{1, 2, 3, 4} {
fmt.Printf("%p\n", &n)
}
當您存儲迭代變量的地址時,或者當您在循環內的閉包中使用它時,當您取消引用指針時,它的值可能已經改變。靜態分析工具會檢測到這一點并發出您看到的警告。
防止該問題的常見方法是:
索引范圍切片/數組/映射。這將獲取第 i 個位置的實際元素的地址,而不是迭代變量
for i := range versions {
res := createWorkerFor(&versions[i])
}
重新分配循環內的迭代變量
for _, v := range versions {
v := v
res := createWorkerFor(&v) // this is now the address of the inner v
}
使用閉包,將迭代變量作為參數傳遞給閉包
for _, v := range versions {
go func(arg ObjectDescription) {
x := &arg // safe
}(v)
}
如果您在循環中按順序取消引用并且您確定沒有任何內容泄漏指針,您可能會忽略此檢查而僥幸逃脫。然而,linter 的工作正是報告可能導致問題的代碼模式,因此無論如何修復它都是一個好主意。

TA貢獻1851條經驗 獲得超5個贊
索引將解決問題:
for i := range versions {
res := createWorkerFor(&versions[i])
...
}
- 2 回答
- 0 關注
- 564 瀏覽
添加回答
舉報