🚲

[golang] Implicit memory aliasing in for loop. の解決法

2021/10/17に公開

解決法

for index, user := range usersとしてuserのポインタにアクセスしていたことが原因。
for index := range usersとしてuser[i]を利用して、ポインタにアクセスすれば解決する。

なぜ駄目なのか

for index, user := range users
goでは上記のuserのアドレスは一定に保たれるらしい。
したがって、for文を回しているのに、同じ場所を指し示し続ける状況になってしまう。
これがImplicit memory aliasingという部分だろう。
Golandでもerrorやwarningを吐いてくれなかったので、知らないうちに大きな事態になることが怖い。
気をつけます。

実装例

before.go
func NewResultUsers(users []User) []ResultUser {
	ru := make([]ResultUser, len(users))
	for i, user := range users {
		ru[i] = *NewResultUser(&user)
	}
	return ru
}
after.go
func NewResultUsers(users []User) []ResultUser {
	ru := make([]ResultUser, len(users))
	for i := range users {
		ru[i] = *NewResultUser(&user[i])
	}
	return ru
}

環境

  • MacBook Air (M1, 2020)
  • go -v 1.15
  • echo -v 4.3.0
  • Docker version 20.10.8, build 3967b7d
  • docker-compose version 1.29.2, build 5becea4c

参考

Discussion