📣
【Go 1.22】for ループの2つの仕様変更
Go 1.22 がリリースされましたね。
本記事では、個人的に今リリースで最もインパクトの大きい仕様変更である、for ループに関する2つの変更について簡単にまとめます。
変数がイテレート毎に宣言されるようになった
1.21 以前では、for ループの range 句で宣言された変数は各イテレートで値が更新されながら使いまわされていました。
そのため、宣言された変数を goroutine で使用したり defer による遅延処理で使用するケースなどで面倒な処理が必要でした。
具体的には、別途宣言した変数に代入するか、即時関数の引数として渡す必要がありました。
package main
import (
"fmt"
"time"
)
func main() {
for _, v := range []int{1, 2, 3} {
go func(n int){
fmt.Println(n)
}(v)
}
// ちょっと待つ
time.Sleep(1 * time.Second)
}
package main
import (
"fmt"
"time"
)
func main() {
for _, v := range []int{1, 2, 3} {
n := v
go func(){
fmt.Println(n)
}()
}
// ちょっと待つ
time.Sleep(1 * time.Second)
}
1.22 からは、イテレート毎に新しい変数が宣言されるようになりました。
1.21 以前で行っていたような処理は不要となり、変数をそのまま goroutine や defer で使用するだけで各イテレートで宣言された変数を用いた動作が得られます。
package main
import (
"fmt"
"time"
)
func main() {
for _, v := range []int{1, 2, 3} {
go func(){
fmt.Println(v)
}()
}
// ちょっと待つ
time.Sleep(1 * time.Second)
}
range 句の式に整数を渡せるようになった
1.21 以前では、0
から2
までの範囲で処理したいといったように、0から任意の正の数まで1ずつ増加する値をループで処理したい場合は、[]int{0, 1, 2}
を渡したり、要素数が3つの何らかのスライスを渡す必要がありました。
package main
import (
"fmt"
)
func main() {
for _, v := range []int{0, 1, 2} {
fmt.Println(v)
}
}
1.22 からは range 句の式に整数を渡すことで、0
から渡した整数 -1
までの範囲を反復して処理できるようになりました。
package main
import (
"fmt"
)
func main() {
for v := range 3 {
fmt.Println(v)
}
}
Discussion