Rustのbreak / continue
break と continue を使うと、ループを最後までまわさずに、途中で流れを変えられます。どちらも、loop、while、for の3種類のループすべてで同じように使えます。
break — ループを完全に抜ける
Section titled “break — ループを完全に抜ける”break はループをその場ですぐに止めます。処理は、ループのすぐ後ろにあるコードへ移ります。
fn main() { for i in 1..=10 { if i == 5 { break; } println!("{i}"); }}実行結果:
1234範囲は10まであるのに、i が5になった瞬間にループは止まります。
continue — 次の回へ飛ばす
Section titled “continue — 次の回へ飛ばす”continue はループ全体を止めるのではなく、今回の残りの処理を飛ばして、すぐに次の回へ進みます。
fn main() { for i in 1..=10 { if i % 2 == 0 { continue; // 偶数は飛ばす } println!("{i}"); }}実行結果:
13579偶数はすべて飛ばされます。continue が実行されると、println! を通らずに、ループはそのまま次の i の値へ進むからです。
ラベル付きループ
Section titled “ラベル付きループ”ループの中に別のループを入れ子にしたとき、ふつうの break / continue が効くのはいちばん内側のループだけです。入れ子の内側から外側のループを抜けたいときは、外側のループにラベルを付けます('名前: のように書きます)。
fn main() { 'outer: for x in 1..=3 { for y in 1..=3 { if x * y > 4 { break 'outer; } println!("{x} x {y} = {}", x * y); } }}実行結果:
1 x 1 = 11 x 2 = 21 x 3 = 32 x 1 = 22 x 2 = 4ラベルがなければ、break で止まるのは内側の y のループだけで、x のループは続いてしまいます。break 'outer; なら両方をいっぺんに止められます。完全に止めるのではなく、外側のループの次の回へ飛びたいときは、同じように continue 'outer; が使えます。
while ループでの continue の落とし穴
Section titled “while ループでの continue の落とし穴”for ループでは、次の値は範囲から自動的に出てくるので、continue はいつでも安全です。while ループでは事情が違います。カウンタを更新するのは自分で、たいていは本体の一番下で更新します。continue がその更新を飛び越えてしまうと、カウンタはいつまでも変わらず、ループは永遠に回り続けます。
次のコードは3を飛ばそうとしていますが、固まってしまいます。実行しないでください。
fn main() { let mut i = 0; while i < 5 { if i == 3 { continue; // ❌ i を変えないまま先頭に戻ってしまう } println!("{i}"); i += 1; }}i が3のとき、continue で条件のところに戻ります。i はまだ3のままなので、また continue が実行され、それが永遠にくり返されます。直し方は、continue するかもしれない処理より前にカウンタを更新することです。
fn main() { let mut i = 0; while i < 5 { i += 1; // 先に更新しておけば、continue で飛ばされない if i == 3 { continue; } println!("{i}"); }}実行結果:
1245i += 1 を先頭に移すと、数が1つずれます。このループは0から4ではなく1から5を表示するので、元の範囲が必要なら、開始値か条件を調整しましょう。さらに言えば、ただ数を数えるだけなら、範囲に対するforループを使えば、この問題はそもそも起きません。
1. 3の倍数を飛ばす
Section titled “1. 3の倍数を飛ばす”1から10までの数を表示します。ただし、3の倍数はすべて飛ばしてください。ヒント:n % 3 == 0 のとき、その数は3の倍数です。continue を使って飛ばしましょう。
解答を見る
fn main() { for n in 1..=10 { if n % 3 == 0 { continue; } println!("{n}"); }}実行結果:
124578102. 掛けて24になるペアを探す
Section titled “2. 掛けて24になるペアを探す”x と y の2つの for ループを入れ子にし、どちらも 1..=9 をまわします。x * y == 24 になる最初のペアを見つけて表示し、両方のループを止めてください。ヒント:外側のループにラベルを付けて、break 'outer; を使います。
解答を見る
fn main() { 'outer: for x in 1..=9 { for y in 1..=9 { if x * y == 24 { println!("見つけました: {x} x {y} = 24"); break 'outer; } } } println!("探索を終了しました");}実行結果:
見つけました: 3 x 8 = 24探索を終了しましたbreak 'outer; をただの break; に変えてみましょう。すると内側のループしか止まらないので、探索が続き、4 x 6、6 x 4、8 x 3 も表示されます。
breakはループをすぐに抜けます。continueは今回の残りの処理を飛ばして、次の回へ進みます。- ラベル(
'outer:)を付けると、入れ子の内側からbreak/continueで外側のループを指定できます。 whileループでは、continueより前にカウンタを更新しましょう。そうしないと、ループが永遠に止まらなくなることがあります。
理解度チェック
Section titled “理解度チェック”理解度チェック
1. ループの中で continue はどんな働きをしますか?
2. 入れ子のループから break で指定できるように、ループにラベルを付けるにはどう書きますか?
3. continue を使った while ループがいつまでも終わりません。いちばん考えられる原因は何ですか?
スコア: 0 / 3
さらに詳しく
Section titled “さらに詳しく”- 複数のループを区別するループラベル — The Rust Programming Language 日本語版:入れ子のカウントダウンを例に、ラベルを紹介する公式の入門です。
- ネストとラベル — Rust By Example 日本語版:
break 'outerとcontinue 'outerの短い実行できるサンプルです。 - Loop Labels — The Rust Reference(英語):ラベルをどこで使えるかの正確なルールです。
breakexpressions — The Rust Reference(英語):値を返すbreakも含めた、breakの働きを説明しています。continueexpressions — The Rust Reference(英語):ループの種類ごとに、continueが何をするかを説明しています。