Home >Backend Development >Golang >Why doesn't modifying a struct in a Go range loop update the original slice?
Ranging Over Structures in Go
In Go, when ranging over a slice of structures, the values obtained from the range variable are copies. As such, any modifications made to these values will not affect the original slice.
Consider the following example:
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) } }
Running this code will produce the following output:
======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
As you can see, the values in the chartRecords slice are not modified, even though we incremented the Count field of each element in the range. This is because the range variable elem is a copy of the original element in the slice.
To update the original slice, you need to assign the updated element back to the slice at the corresponding index:
for i, elem := range chartRecords { elem.Count++ chartRecords[i] = elem }
With this correction, running the code again will produce the following output:
======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
Now, the values in the chartRecords slice are updated as expected.
The above is the detailed content of Why doesn't modifying a struct in a Go range loop update the original slice?. For more information, please follow other related articles on the PHP Chinese website!