Golang pass-by-value in “for … range” loops
Most things in Go pass by value, but this one still surprised me.
func main() {
points := []Point{{x: 1, y: 1}}
for _, p := range points {
p.x += 1
}
fmt.Println(points[0].x) // Expected "2" but got "1". :(
}
range
returns a copy of the value in each iteration of the loop.
Changes to the copy don’t survive exit of the loop.
If we want changes to persist, we need to modify the original:
// Demonstrate pass-by-value in "for" loops.
package main
import "fmt"
type Point struct {
x int
y int
}
func main() {
points := []Point{{x: 1, y: 1}}
for i, p := range points {
fmt.Println(p.x) // 1
p.x += 1
fmt.Println(p.x) // 2
fmt.Println(points[i].x) // 1 not 2! "p" is only a copy of points[i].
points[i].x += 1 // This modifies the original value, outside the loop.
}
fmt.Println(points[0].x) // 2
}
#golang