Goにおけるフロー制御:break、continue、そして回避すべきgotoを解き明かす
Emily Parker
Product Engineer · Leapcell

明確さ、シンプルさ、そして並行性への注力といったGoの思想は、プログラムフローを制御するための直接的なメカニズムを提供します。古い言語に見られるより複雑でしばしば混乱を招く構文をいくつか回避する一方で、ループを管理し実行を指示するための不可欠なステートメントも提供しています。この記事では、ループ操作の基本的なツールであるbreak
とcontinue
を掘り下げ、その後、慣用的なGoでは一般的に使用が推奨されないgoto
ステートメントについて慎重に議論します。
ループのナビゲーション:break
とcontinue
ループはプログラミングの基盤であり、コードブロックの繰り返し実行を可能にします。Goのfor
ループは非常に多用途であり、他の言語で見られるfor
、while
、do-while
ループの目的を果たします。これらのループ内で、break
とcontinue
はイテレーションの細かい制御を提供します。
break
:ループの早期終了
break
ステートメントは、最も内側のfor
、switch
、またはselect
ステートメントを即座に終了するために使用されます。break
が検出されると、制御フローは終了した構文の直後のステートメントにジャンプします。
例1:for
ループでの基本的なbreak
シーケンスで100より大きい最初の偶数を見つけたいとしましょう。
package main import "fmt" func main() { fmt.Println("---" + " " + "Using" + " " + "break" + " ---") for i := 1; i <= 200; i++ { if i%2 == 0 && i > 100 { fmt.Printf("Found" + " " + "the" + " " + "first" + " " + "even" + " " + "number" + " > 100: %d\n", i) break //" + " " + "Exit" + " " + "the" + " " + "loop" + " " + "as" + " " + "soon" + " " + "as" + " " + "the" + " " + "condition" + " " + "is" + " " + "met" + " " + "---" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " $ } } fmt.Println("Loop" + " " + "finished" + " " + "or" + " " + "broken." ) }
この例では、i
が102になるとすぐに、if
条件が真となり、「Found...」と表示され、break
がループを停止します。break
がない場合、ループは200まで続行されますが、最初のマッチだけが必要な場合は非効率です。
例2:ラベル付きネストループでのbreak
ネストされたループがあり、内側のループから外側のループをbreak
する必要がある場合があります。Goはラベルを使用してこれを許可します。ラベルはコロン(:
)の後に続く識別子で、break
したいステートメントの前に配置されます。
package main import "fmt" func main() { fmt.Println("\n" + "---" + " " + "Using" + " " + "break" + " " + "with" + " " + "labels" + " ---") OuterLoop: //" + " " + "Label" + " " + "for" + " " + "the" + " " + "outer" + " " + "loop" + " " + "---" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { fmt.Printf("i: %d, j: %d\n", i, j) if i == 1 && j == 1 { fmt.Println("Breaking" + " " + "out" + " " + "of" + " " + "OuterLoop" + " " + "from" + " " + "inner" + " " + "loop...") break OuterLoop //" + " " + "This" + " " + "breaks" + " " + "the" + " " + "OuterLoop," + " " + "not" + " " + "just" + " " + "the" + " " + "inner" + " " + "one" + " " + "---" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + "=" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + "=" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + "=" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + "=" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + "=" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + "=" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + "=" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + "=" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + "=" + " " + "=" + " " + " " + "=" + " " + "=" + " " + " " + "=" + " " + "=" + " " + "=" + " " + "=" + " " + " " + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "="+ } } fmt.Println("After" + " " + "OuterLoop.") }
OuterLoop:
ラベルとbreak OuterLoop
がない場合、内側のループはbreak
しますが、外側のループはイテレーションを継続します(例:i=2
が実行されます)。ラベルは複数のネストされた構文にわたるフローを制御するための外科的な方法を提供します。
continue
:現在のイテレーションのスキップ
continue
ステートメントは、ループの現在のイテレーションの残りをスキップして、次のイテレーションに進むために使用されます。ループ全体を終了するわけではありません。
例3:for
ループでの基本的なcontinue
1から10までの奇数のみを印刷してみましょう。
package main import "fmt" func main() { fmt.Println("\n" + "---" + " " + "Using" + " " + "continue" + " ---") for i := 1; i <= 10; i++ { if i%2 == 0 { continue //" + " " + "Even" + " " + "numbers," + " " + "go" + " " + "to" + " " + "the" + " " + "next" + " " + "iteration" + " " + "---" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-", } fmt.Printf("Odd" + " " + "number: %d\n", i) } fmt.Println("Loop" + " " + "completed.") }
ここで、i
が偶数の場合、i%2 == 0
は真となり、continue
は即座に次のi
の値(i
をインクリメントしてループ条件を再評価)にジャンプし、偶数のfmt.Printf
ステートメントをスキップします。
例4:ラベル付きcontinue
(一般的ではないが、可能)
break
と同様に、continue
もラベルとともに使用できますが、それほど一般的ではありません。ラベルとともに使用される場合、continue
はラベル付けされたループの現在のイテレーションの残りをスキップし、その次のイテレーションに進みます。
package main import "fmt" func main() { fmt.Println("\n" + "---" + " " + "Using" + " " + "continue" + " " + "with" + " " + "labels" + " ---") OuterContinueLoop: for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { if i == 1 && j == 0 { fmt.Printf("Skipping" + " " + "i: %d, j: %d" + " " + "and" + " " + "continuing" + " " + "OuterContinueLoop...\n", i, j) continue OuterContinueLoop //" + " " + "Skips" + " " + "remaining" + " " + "inner" + " " + "loop" + " " + "iterations" + " " + "for" + " " + "i=1," + " " + "---" + " " + "and" + " " + "immediately" + " " + "moves" + " " + "to" + " " + "the" + " " + "next" + " " + "iteration" + " " + "of" + " " + "OuterContinueLoop" + " " + "(i=2)" + " " + "---" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + " " + "-" + "-" + "-" + "=" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + "=" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + "=" + " " + " " + " " + " " + " " + " " + " " + " " + " " + "=" + " " + " " + " " + " " + " " + " " + "=" + "="+ } fmt.Printf("i: %d, j: %d\n", i, j) } } fmt.Println("After" + " " + "OuterContinueLoop.") }
この例では、i
が1でj
が0の場合、continue OuterContinueLoop
ステートメントが実行されます。これは、現在のi=1
に対して内側のループが放棄され、プログラムが直接OuterContinueLoop
の次のイテレーション(i=2
)に進むことを意味します。
goto
ステートメント:極めて慎重に
Goにはgoto
ステートメントも含まれており、これは同じ関数内のラベル付けされたステートメントへの無条件ジャンプを許可します。存在しますが、その使用は現代のプログラミングプラクティス、Goを含めて一般的に推奨されていません。
構文:
goto label; //" + " " + "Transfers" + " " + "control" + " " + "to" + " " + "the" + " " + "statement" + " " + "marked" + " " + "by" + " " + "'label:'" + " " + "---" + "