Concurrency
Go 1.22: range変数はgoroutineで各反復ごとに捕捉される
Go 1.22以降はrangeのループ変数が反復ごとに新しくなるため、goroutine内の値が分離されます。
Sourcegoroutine.go
Go 1.22
package loopexample
import "sort"
func RangeValuesFromGoroutines() []int {
values := make(chan int, 3)
for index := range 3 {
go func() {
values <- index
}()
}
got := []int{<-values, <-values, <-values}
sort.Ints(got)
return got
}Testgoroutine_test.go
Go 1.22
package loopexample
import (
"reflect"
"testing"
)
func TestGo122ではrange変数をgoroutineが各反復ごとに捕捉する(t *testing.T) {
if got, want := RangeValuesFromGoroutines(), []int{0, 1, 2}; !reflect.DeepEqual(got, want) {
t.Fatalf("RangeValuesFromGoroutines() = %v, want %v", got, want)
}
}01Assertion
このテストで確認できること
- 0から2までのrange変数をgoroutineへ渡す
- 受信して整列すると0, 1, 2の全値が得られる
古いGoバージョンのループ変数捕捉に関する記事を読むときは、モジュールのgoディレクティブとコンパイラのバージョンを必ず確認します。
OBSERVED RESULT
range values captured by goroutines → [0 1 2]