概要
Goのfor-rangeで渡される第2引数はコピーであることが分かったので投稿します。
Go: 1.21
実例
以下の例だと、for i, v := range people
のvの値はpeopleの1つ目の要素のコピーなので、vの値を変えても、大元のpeopleの値は変更されません。
コピーなのでfmt.Println(&people[i] == &v)
のメモリアドレスの比較でもfalseになります。
package main
import (
"fmt"
)
type person struct {
name string
}
func main() {
people := []person{
{name: "aだよ"},
}
for i, v := range people {
fmt.Println(&people[i] == &v) // false
v.name = "名前変わったよ"
fmt.Println(v.F()) // 名前変わったよ
}
fmt.Println(people) // [{aだよ}]
}
func (p *person) F() string {
return p.name
}
大元の値を変えたい場合は以下のようにコードを変更する必要があります。
package main
import (
"fmt"
)
type person struct {
name string
}
func main() {
people := []person{
{name: "aだよ"},
}
for i := range people {
people[i].name = "名前変わったよ"
}
fmt.Println(people) // [{名前変わったよ}]
}
ただ、大元の値(今回だとpeople
)を変更して後続のコードに影響があるかもしれないので使用する場合は注意が必要です。