Go言語入門:言語仕様 -Vol.120-

スポンサーリンク
Go言語入門:言語仕様 -Vol.120- 用語解説
Go言語入門:言語仕様 -Vol.120-
この記事は約6分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

本日は、Go言語の言語仕様について解説しています。

スポンサーリンク

背景

Go言語を学び始めて、公式の「The Go Programming Language Specification(言語仕様書)」を開いてみたものの、「英語で書かれていて読むのが大変…」「専門用語ばかりで何を言っているのかわからない…」と感じたことはありませんか? 実は、多くのGo初心者が同じ壁にぶつかっています。

言語仕様書は、Go言語の「正式な取扱説明書」のような存在です。プログラミング言語がどのように動くのか、どんなルールで書くべきなのかが詳しく書かれていますが、その分、初めて読む人には難しく感じられるのも事実です。

そこでこの記事では、言語仕様書の導入部分を丁寧な日本語訳とともに、初心者の方でも理解しやすい補足説明を加えてお届けします。「強く型付けされている」「ガベージコレクション」「並行プログラミング」といった専門用語も、具体例を交えながらわかりやすく解説していきます。

言語仕様書は難しそうに見えますが、一つひとつの概念を丁寧に読み解いていけば、必ず理解できます。一緒に、Go言語の基礎をしっかり学んでいきましょう!

continue文(Continue statements)

continue 文は、ループブロックの末尾に制御を進めることで、最も内側の囲んでいる for ループの次の反復を開始する。for ループは同じ関数内でなければならない。

ContinueStmt = "continue" [ Label ] .

ラベルがある場合、それは囲んでいる for 文のラベルでなければならず、その文の実行が進められる。

RowLoop:
	for y, row := range rows {
		for x, data := range row {
			if data == endOfRow {
				continue RowLoop
			}
			row[x] = data + bias(x, y)
		}
	}

解説

continue の基本

continue は、現在の反復の残りをスキップして、次の反復に進む文です。

for i := 0; i < 10; i++ {
    if i%2 == 0 {
        continue  // 偶数ならスキップ
    }
    fmt.Println(i)
}
// 出力: 1, 3, 5, 7, 9

break がループ全体を終了するのに対し、continue今回の反復だけをスキップして次へ進みます。

break との違いを視覚化

for i := 0; i < 5; i++ {
    if i == 3 {
        break      // ループ自体が終了。4 は出力されない
    }
    fmt.Println(i)
}
// 出力: 0, 1, 2

for i := 0; i < 5; i++ {
    if i == 3 {
        continue   // 3 だけスキップ。ループは続く
    }
    fmt.Println(i)
}
// 出力: 0, 1, 2, 4

continue と for の各部分の関係

3部構成の for 文で continue を使うと、後置文はスキップされずに実行されます。

for i := 0; i < 10; i++ {  // i++ は continue しても実行される
    if i == 5 {
        continue  // ループ本体の残りをスキップ → i++ → 条件チェック → 次の反復
    }
    fmt.Println(i)
}

これは「ループブロックの末尾に制御を進める」という原文の表現と一致しています。ブロックの末尾に進むということは、後置文が実行される位置に到達するということです。

switch や select には使えない

continuefor ループ専用です。switchselect には使えません。

for i := 0; i < 10; i++ {
    switch i {
    case 5:
        continue  // ✅ これは外側の for の次の反復に進む
    }
}

switch の中に continue があると、それは switch ではなく外側の for に作用します。break とは逆の関係ですね(break は最も内側の for/switch/select を抜ける)。

ラベル付き continue

ネストしたループで、外側のループの次の反復に進みたいときにラベルを使います。

RowLoop:
    for y, row := range rows {
        for x, data := range row {
            if data == endOfRow {
                continue RowLoop  // 外側のループの次の反復(次の行)へ
            }
            row[x] = data + bias(x, y)
        }
    }

ラベルなしの continue だと内側のループの次の反復に進むだけですが、continue RowLoop は外側のループの次の反復に進みます。

// ラベルなし continue
for y := range rows {
    for x := range rows[y] {
        if condition {
            continue  // 次の x へ(内側のループの次の反復)
        }
    }
}

// ラベル付き continue
outer:
for y := range rows {
    for x := range rows[y] {
        if condition {
            continue outer  // 次の y へ(外側のループの次の反復)
        }
    }
}

よくある使い方

1. 条件に合わない要素をスキップ

for _, item := range items {
    if !item.IsValid() {
        continue  // 無効なアイテムはスキップ
    }
    process(item)
}

これは if item.IsValid() { process(item) } と同じ結果ですが、continue を使うとネストが浅くなり読みやすくなります。特に処理が長い場合に効果的です。

2. 早期スキップで処理を整理する

for _, user := range users {
    if user.Deleted {
        continue
    }
    if user.Suspended {
        continue
    }
    if !user.HasPermission(action) {
        continue
    }
    // ここまで来たユーザーだけ処理する
    executeAction(user, action)
}

return を使った早期リターンのループ版ですね。条件に合わないものを先に除外して、メインの処理をネストの浅い場所に書けます。Go らしいスタイルです。

おわりに 

本日は、Go言語の言語仕様について解説しました。

よっしー
よっしー

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました