首頁 >後端開發 >Golang >為什麼在 Go 範圍循環中修改結構體不會更新原始切片?

為什麼在 Go 範圍循環中修改結構體不會更新原始切片?

DDD
DDD原創
2024-12-20 10:45:09466瀏覽

Why doesn't modifying a struct in a Go range loop update the original slice?

Go 中的結構遍歷

在 Go 中,當遍歷結構體切片時,從 range 變數獲得的值是副本。因此,對這些值進行的任何修改都不會影響原始切片。

考慮以下範例:

package main

import (
    "fmt"
)

type myStruct struct {
    Name  string
    Count int
}

func main() {
    chartRecords := []myStruct{}

    for i := 0; i < 5; i++ {
        n := myStruct{Count: i, Name: fmt.Sprintf("Joe%2d", i)}
        chartRecords = append(chartRecords, n)
    }

    fmt.Printf("======ORIGINAL VALUES========\n")
    for _, elem := range chartRecords {
        fmt.Printf("No: %2d | Count: %2d | Name = %s\n", elem.Count, elem.Name)
    }

    fmt.Printf("======MODIFIED VALUES EXPECTED========\n")
    for _, elem := range chartRecords {
        elem.Count++
        fmt.Printf("No: %2d | Count: %2d | Name = %s\n", elem.Count, elem.Name)
    }

    fmt.Printf("======CHECK AGAIN AND VALUES ARE BACK TO ORIGINAL========\n")
    for _, elem := range chartRecords {
        fmt.Printf("No: %2d | Count: %2d | Name = %s\n", elem.Count, elem.Name)
    }
}

執行此程式碼將產生以下輸出:

======ORIGINAL VALUES========
No:  0 | Count:  0 | Name = Joe 0
No:  1 | Count:  1 | Name = Joe 1
No:  2 | Count:  2 | Name = Joe 2
No:  3 | Count:  3 | Name = Joe 3
No:  4 | Count:  4 | Name = Joe 4
======MODIFIED VALUES EXPECTED========
No:  1 | Count:  1 | Name = Joe 0
No:  2 | Count:  2 | Name = Joe 1
No:  3 | Count:  3 | Name = Joe 2
No:  4 | Count:  4 | Name = Joe 3
No:  5 | Count:  5 | Name = Joe 4
======CHECK AGAIN AND VALUES ARE BACK TO ORIGINAL========
No:  0 | Count:  0 | Name = Joe 0
No:  1 | Count:  1 | Name = Joe 1
No:  2 | Count:  2 | Name = Joe 2
No:  3 | Count:  3 | Name = Joe 3
No:  4 | Count:  4 | Name = Joe 4

如您所見,即使我們增加了範圍內每個元素的Count 字段,chartRecords 切片中的值也不會被修改。這是因為範圍變數 elem 是切片中原始元素的副本。

要更新原始切片,需要將更新後的元素分配回相應索引處的切片:

for i, elem := range chartRecords {
    elem.Count++
    chartRecords[i] = elem
}

進行此更正後,再次運行程式碼將產生以下輸出:

======ORIGINAL VALUES========
No:  0 | Count:  0 | Name = Joe 0
No:  1 | Count:  1 | Name = Joe 1
No:  2 | Count:  2 | Name = Joe 2
No:  3 | Count:  3 | Name = Joe 3
No:  4 | Count:  4 | Name = Joe 4
======MODIFIED VALUES EXPECTED========
No:  1 | Count:  1 | Name = Joe 0
No:  2 | Count:  2 | Name = Joe 1
No:  3 | Count:  3 | Name = Joe 2
No:  4 | Count:  4 | Name = Joe 3
No:  5 | Count:  5 | Name = Joe 4
======CHECK AGAIN AND VALUES ARE STILL MODIFIED========
No:  1 | Count:  1 | Name = Joe 0
No:  2 | Count:  2 | Name = Joe 1
No:  3 | Count:  3 | Name = Joe 2
No:  4 | Count:  4 | Name = Joe 3
No:  5 | Count:  5 | Name = Joe 4

現在,chartRecords 切片中的值已更新正如預期的那樣。

以上是為什麼在 Go 範圍循環中修改結構體不會更新原始切片?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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