首頁 >後端開發 >Golang >為什麼 Go 的切片範圍循環在與 Map 一起使用時會產生意外的行為?

為什麼 Go 的切片範圍循環在與 Map 一起使用時會產生意外的行為?

Linda Hamilton
Linda Hamilton原創
2024-12-09 01:54:12394瀏覽

Why Does Go's Slice Range Loop Create Unexpected Behavior When Used with Maps?

解碼 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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn