LoginSignup
1
0

Goのfor-rangeのvalueはコピーであることが分かった

Last updated at Posted at 2024-01-05

概要

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)を変更して後続のコードに影響があるかもしれないので使用する場合は注意が必要です。

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0