理解 Go 中的切片範圍現象
在 Go 中,切片範圍的行為可能會令人困惑。當使用 range 子句迭代切片時,人們很容易相信迭代變數保存了每個元素的位址。然而,情況並非總是如此。其中一個這樣的場景是使用結構體和映射時。
考慮以下程式碼:
type student struct { Name string Age int } func main() { m := make(map[string]*student) s := []student{ {Name: "Allen", Age: 24}, {Name: "Tom", Age: 23}, } for _, stu := range s { m[stu.Name] = &stu } }
此程式碼迭代結構體切片,將鍵值對加到映射中每個結構體,並將結構體的位址儲存為值。然而,產生的映射顯示所有值都指向相同的位址。
為了解釋這個現象,我們需要看看切片範圍的底層實作。當使用 range 子句迭代切片時,迭代變數會從切片接收元素的副本。因此,迭代變數保存結構體的副本,而不是其位址。
要解決此問題並將結構體的位址儲存在映射中,必須修改程式碼以取得切片元素的位址:
for i := range s { m[s[i].Name] = &s[i] }
此變更可確保迭代變數保存結構體的位址,並且映射將正確儲存切片中每個結構體的位址。
以上是為什麼 Go 中的切片範圍迭代有時會傳回副本而不是位址?的詳細內容。更多資訊請關注PHP中文網其他相關文章!