解碼 Go 切片範圍的行為
在 Go 中,切片是一種多功能資料結構,提供類似動態陣列的功能。當迭代切片時,範圍語法提供了一種存取其元素的便捷方法。但是,某些情況可能會導致意外行為。
請考慮以下程式碼,該程式碼建立學生結構體切片並使用這些結構體的引用填充映射:
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 } fmt.Println(m) // map[Allen:0xc42006a0c0 Tom:0xc42006a0c0] }
預期行為是映射應包含對切片中每個單獨學生結構的引用。然而,結果顯示映射中的兩個鍵都指向相同的位址。
可以透過理解範圍循環中的 Stu 變數是切片元素的副本而不是引用來解釋此行為。 Stu.Name 檢索名稱欄位的副本,而 &stu 取得該副本的位址,從而為所有映射值提供相同的位址。
要更正此問題,程式碼應取得該副本的位址實際的切片元素:
for i := range s { m[s[i].Name] = &s[i] }
透過直接存取切片元素,我們獲得對其唯一記憶體位置的引用,解決意外行為並確保映射包含對每個學生的引用結構。
以上是為什麼 Go 的切片範圍循環在與 Map 一起使用時會產生意外的行為?的詳細內容。更多資訊請關注PHP中文網其他相關文章!