制御構造

Go言語のfor文について解説:基本構文からrange句の使用例まで

Go言語のfor文は、シンプルながらも柔軟に繰り返し処理を実装できる構文です。

この記事では、基本的な使い方に加え、条件付きやrangeを用いた例も紹介し、実際のコードから直感的に理解できるよう解説します。

ぜひ手を動かして試してみてください。

基本構文

for文の基本形

初期化・条件・更新の各要素

Goのfor文は、C言語のfor文に似た形式で、初期化式、条件式、更新式の3つの要素を指定できます。

下記のサンプルコードでは、初期化で変数iを0にセットし、条件式でiが5未満の場合にループを継続、更新式でiをインクリメントしています。

package main
import "fmt"
func main() {
	// for文の基本形の例
	for i := 0; i < 5; i++ {
		// カウンタiの値を出力する
		fmt.Printf("ループ回数: %d\n", i)
	}
}
ループ回数: 0
ループ回数: 1
ループ回数: 2
ループ回数: 3
ループ回数: 4

条件式省略時の動作

条件式を省略すると、自動的にtrueとみなされ、無限ループとなります。

ただし、更新やbreak文を適切に使用することで、意図した処理を実現できます。

下記のサンプルでは条件式を省略し、if文によってループの終了条件を設定しています。

package main
import "fmt"
func main() {
	counter := 0
	// 条件式を省略したfor文(無限ループ)
	for {
		if counter >= 3 {
			// counterが3以上ならループを抜ける
			break
		}
		fmt.Printf("カウンタの値: %d\n", counter)
		counter++
	}
}
カウンタの値: 0
カウンタの値: 1
カウンタの値: 2

条件付きfor文

単一条件での利用

Goではfor文の初期化式と更新式を省略し、条件式だけでループを制御することも可能です。

下記のサンプルでは、変数numが10未満の場合にループを継続するシンプルな例を示しています。

package main
import "fmt"
func main() {
	num := 0
	// 単一条件でのfor文
	for num < 10 {
		fmt.Printf("数値: %d\n", num)
		num++
	}
}
数値: 0
数値: 1
数値: 2
数値: 3
数値: 4
数値: 5
数値: 6
数値: 7
数値: 8
数値: 9

無限ループとしての利用

条件式を完全に省略すると、無限ループが実現できます。

無限ループは、終了条件が内部で定義される場合や、サーバーのリスニング処理などで利用されることが多いです。

下記のサンプルでは、if文とbreakを使って、無限ループ内でカウンタが一定値に達した場合にループを終了させる例を示します。

package main
import "fmt"
func main() {
	counter := 0
	// 完全に条件を省略した無限ループ
	for {
		if counter == 4 {
			// カウンタが4になったらループ終了
			break
		}
		fmt.Printf("現在のカウンタ: %d\n", counter)
		counter++
	}
}
現在のカウンタ: 0
現在のカウンタ: 1
現在のカウンタ: 2
現在のカウンタ: 3

range句を使用した反復処理

配列・スライスのループ処理

range句を使うと、配列やスライスの各要素に対して簡単に反復処理を行うことができます。

rangeはループ毎にインデックスと要素の値を返すため、必要に応じてどちらか一方だけを使用することもできます。

下記のサンプルは、整数スライスの各要素を出力する例です。

package main
import "fmt"
func main() {
	numbers := []int{10, 20, 30, 40}
	// range句を利用してスライスの各要素にアクセス
	for index, value := range numbers {
		// インデックスと値を出力する
		fmt.Printf("インデックス: %d, 値: %d\n", index, value)
	}
}
インデックス: 0, 値: 10
インデックス: 1, 値: 20
インデックス: 2, 値: 30
インデックス: 3, 値: 40

マップからのキーと値の取得

range句はマップの各要素に対しても利用できます。

マップでは、range句によりキーと対応する値が返されるため、キーと値のペアを簡単に取得できます。

下記のサンプルは、文字列をキー、整数を値とするマップから情報を出力する例です。

package main
import "fmt"
func main() {
	ages := map[string]int{
		"Alice": 25,
		"Bob":   30,
		"Carol": 28,
	}
	// range句を使用してマップのキーと値を取得する
	for name, age := range ages {
		fmt.Printf("名前: %s, 年齢: %d\n", name, age)
	}
}
名前: Alice, 年齢: 25
名前: Bob, 年齢: 30
名前: Carol, 年齢: 28

文字列の反復処理

Goの文字列はUTF-8でエンコードされており、range句を使うと各文字(正確にはルーン)を正しく取得できます。

下記のサンプルでは、文字列内の各文字を反復処理し、ルーンとそのインデックスを出力しています。

package main
import "fmt"
func main() {
	str := "こんにちは"
	// range句で文字列の各ルーンにアクセス
	for index, char := range str {
		// インデックスとルーン(文字)を出力する
		fmt.Printf("インデックス: %d, 文字: %c\n", index, char)
	}
}
インデックス: 0, 文字: こ
インデックス: 3, 文字: ん
インデックス: 6, 文字: に
インデックス: 9, 文字: ち
インデックス: 12, 文字: は

応用例と注意点

よくあるミスの例

意図しない無限ループの回避方法

ループ内で更新式を書き忘れると、意図しない無限ループが発生することがあります。

下記のサンプルは、更新式を忘れた場合の例と、その回避方法をコメントで示しています。

(以下のサンプルコードは正しい実装例です。

更新式を忘れずに記述する点を強調しています。)

package main
import "fmt"
func main() {
	counter := 0
	// 更新式がないと無限ループになりかねないため、必ずカウンタの更新を行う
	for counter < 5 {
		fmt.Printf("カウンタ: %d\n", counter)
		// ここでカウンタを更新しないと無限ループになる
		counter++
	}
}
カウンタ: 0
カウンタ: 1
カウンタ: 2
カウンタ: 3
カウンタ: 4

効率的なfor文の活用シーン

for文は、単純なカウンタ制御からコレクションの反復に至るまで、さまざまなシーンで効率的に利用できます。

特に、range句を用いることでエラーが起こりにくくなり、コードが短く読みやすくなるため、配列、スライス、マップ、文字列操作などでは積極的に使用するのが良いでしょう。

例えば、ループ処理によるデータの集計や、条件を満たす要素の探索など、シンプルな処理でもfor文を適切に使うことで、パフォーマンスと可読性が向上します。

また、無限ループを利用することで、一度の初期化で継続的な監視や待機処理を実装することも可能です。

必要な部分で明示的にbreakreturnを記述することで、意図しないループの持続を防ぎ、安定した動作が期待できます。

まとめ

この記事ではGo言語のfor文の基本構文、条件付きfor文、range句を用いた反復処理、応用例と注意点について詳しく解説しました。

for文の各形式や更新式の重要性、無限ループの回避方法などを正しく理解し、効率的なコード作成が可能になる点を把握できます。

ぜひ、ご自身の開発に取り入れて、さらにGo言語の実践力を高めてください。

関連記事

Back to top button
目次へ