Go/range
表示
< Go
Goの range キーワードは、配列、スライス、文字列、マップ、チャネルといった様々なコレクション型の要素を簡潔に反復処理するための強力な構文です。for ループと組み合わせて使用され、Goプログラミングにおいて欠かせない機能の一つと言えるでしょう。
基本構文
[編集]for インデックス, 要素 := range コレクション { // 繰り返し処理 }
range 式で指定されたコレクションの要素数だけループが実行され、各イテレーションにおいて、第一の変数には要素のインデックス(またはキー)、第二の変数には要素の値が代入されます。第二の変数が不要な場合は _(ブランク識別子)で省略できます。
range は以下の型のコレクションに対して使用でき、それぞれ異なる動作をします。
- 配列・スライス・ポインタ to 配列:
- 第一変数: 要素のインデックス(
int型) - 第二変数: 要素の値
- 第一変数: 要素のインデックス(
- 文字列:
- マップ:
- 第一変数: キー
- 第二変数: 値
- チャネル:
- 第一変数: チャネルから受信した値
- (第二変数はありません)
- 整数値(Go 1.22以降):
- 第一変数:
0からn-1までの整数値(nはrangeの後の整数値) - (第二変数はありません)
- 第一変数:
- イテレータ関数(Go 1.23以降):
- 関数のシグネチャによって、一つまたは複数の値が返されます。
使用例
[編集]- 配列やスライスの要素とインデックスを出力
package main import "fmt" func main() { var a = [3]string{"apple", "banana", "cherry"} for i, s := range a { fmt.Printf("インデックス: %d, 値: %s\n", i, s) } fmt.Println() // 文字列の各Unicode符号点とそのバイトインデックスを出力 for i, r := range "こんにちは" { fmt.Printf("%d: %c\n", i, r) } fmt.Println() // マップのキーと値を表示(順序は保証されません) m := map[string]int{"apple": 100, "banana": 200, "cherry": 300} for key, val := range m { fmt.Printf("キー: %s, 値: %d\n", key, val) } fmt.Println() // チャネルから受信した値を順に出力 ch := make(chan int, 2) go func() { ch <- 1 ch <- 2 close(ch) }() for v := range ch { fmt.Println("受信:", v) } fmt.Println() // 0から4までの整数値を順に出力(Go 1.22以降) for i := range 5 { fmt.Println("数値:", i) } fmt.Println() // イテレータ関数を用いたフィボナッチ数列の生成と出力(Go 1.23以降) fibo := func(yield func(x int) bool) { f0, f1 := 0, 1 for yield(f0) { f0, f1 = f1, f0+f1 } } fmt.Print("フィボナッチ数列: ") for x := range fibo { if x >= 1000 { break } fmt.Printf("%d ", x) } fmt.Println() }
特記事項
[編集]- 変数の省略:
- インデックスのみが必要な場合は
for i := range collection { ... }のように記述します。 - 値のみが必要な場合は
for _, v := range collection { ... }のようにブランク識別子_を使用します。
- インデックスのみが必要な場合は
range式の評価:rangeの後のコレクションの式は、ループ開始前に一度だけ評価されます。ただし、変数が1つ以下で、式や長さがコンパイル時に定数の場合は、評価が省略されることがあります。- マップの反復順序: マップの
rangeによる反復処理では、要素の順序は保証されません。実行ごとに順序が変わる可能性があります。 nil値の扱い:- 変数のスコープ:
:=を用いてforループ内で宣言された変数は、そのforブロック内でのみ有効です。Go 1.22以降では、ループの各イテレーションで新しい変数が作成されるため、クロージャ内で変数を参照する際の注意点が変更されています。
range キーワードは、Goでコレクションデータを効率的かつ簡潔に処理するための強力なツールです。これらの特性を理解し、適切に活用することで、より可読性が高く、保守性の高いコードを書くことができるでしょう。