Rustのwhile
while ループは、条件が true である間ずっと動き続けます。何回かかるかは正確にわからなくても、何を待っているのかはわかっている。そんなときにぴったりの道具です。
基本的なwhileループ
Section titled “基本的なwhileループ”fn main() { let mut count = 1;
while count <= 5 { println!("{count}"); count += 1; }}実行結果:
12345条件(count <= 5)は、ループを1回まわる前に毎回チェックされます。条件が false になった時点でループは終わります。この例では、count が6になったところで終わります。
whileとloopの比較
Section titled “whileとloopの比較”同じことは loop と手書きの if/break でも書けます。でも while のほうが、「これが真である間は続ける」という意図をそのまま表せます。loop は、止める条件がループの先頭に自然に置けない場合のためにとっておきましょう。
// whileで書くと — すっきりして要点がはっきりするlet mut n = 0;while n < 3 { println!("{n}"); n += 1;}
// 同じことをloopで書くと — 動くけれど、読む量が多いlet mut n = 0;loop { if n >= 3 { break; } println!("{n}"); n += 1;}もう少し実践的な例
Section titled “もう少し実践的な例”while は、値が目標に届くまで待つ、といった場面でよく使われます。
fn main() { let mut balance = 100;
while balance < 200 { balance += 25; println!("残高は{balance}円になりました"); }
println!("目標に到達しました!");}実行結果:
残高は125円になりました残高は150円になりました残高は175円になりました残高は200円になりました目標に到達しました!条件には bool になる式なら何でも書けます。演算子のページで学んだ && や || を使って、while balance < 200 && months < 12 のようにチェックを組み合わせることもできます。
Rustにはdo-whileがない
Section titled “Rustにはdo-whileがない”言語によっては、do { ... } while (条件) というループがあります。本体を先に実行してから条件をチェックするので、本体は必ず1回は実行されます。Rustにはこれがありません。代わりに loop を使い、チェックを最後に置きます。
これが効いてくる例を見てみましょう。数の桁数を数えるには、何も残らなくなるまで10で割り続ければよいですね。でも 0 という数も1桁なのに、ふつうの while ループでは一度も実行されません。
fn main() { let number = 0;
// whileは先にチェックするので、0のときは一度も実行されない let mut n = number; let mut digits = 0; while n > 0 { digits += 1; n /= 10; } println!("whileでは{number}は{digits}桁");
// loopと最後のチェックなら、本体は少なくとも1回実行される let mut n = number; let mut digits = 0; loop { digits += 1; n /= 10; if n == 0 { break; } } println!("loopでは{number}は{digits}桁");}実行結果:
whileでは0は0桁loopでは0は1桁number を 4096 に変えると、どちらも4桁で一致します。違いが出るのは、最初から条件が偽のときだけです。そこで目安としては、本体を少なくとも1回は実行しなければならないなら、loop を使って一番下に if ... { break; } を書きましょう。
while ループにはもう1種類、値がパターンに当てはまる間続ける while let があります。これはif let / while letのページで扱っています。
1. 100を超えるまで足す
Section titled “1. 100を超えるまで足す”1 + 2 + 3 + … と足していき、合計が100を超えたところで止めてください。いくつの数を足したかと、合計を表示しましょう。ヒント:mut の変数が2つ必要です。1つは次に足す数、もう1つは合計です。
解答を見る
fn main() { let mut next = 1; let mut total = 0;
while total <= 100 { total += next; next += 1; }
println!("{}個の数を足して、合計は{total}", next - 1);}実行結果:
14個の数を足して、合計は105最後の1回が終わった時点で、next はもう1つ先に進んでいます。だから next - 1 を表示しているのです。こうした「1つずれ」の細かい点は、小さな例を頭の中でたどって確かめる価値があります。
2. 1になるまで半分にする
Section titled “2. 1になるまで半分にする”1000から始めます。数が1より大きい間、2で割って(整数の割り算)その数を表示してください。最後に、何回半分にしたかを表示します。ヒント:n /= 2 は n を2で割り、余りを捨てます。
解答を見る
fn main() { let mut n = 1000; let mut steps = 0;
while n > 1 { n /= 2; steps += 1; println!("{n}"); }
println!("1になるまで{steps}回半分にしました");}実行結果:
5002501256231157311になるまで9回半分にしました125 / 2 は 62.5 ではなく 62 になります。どちらの数も整数だからです。そのおかげで、ループはちょうど1で終わります。
while 条件 { ... }は、条件がtrueである間くり返します。条件は毎回、まわる前にチェックされます。- ループの中のどこかで、いずれ条件が
falseになるようにしましょう。そうしないと永遠に動き続けます。 - 止める条件が「Xが成り立つ間」という形で自然に書けるときは、
loopよりwhileを選びましょう。 - Rustにはdo-whileがありません。本体を少なくとも1回実行したいときは、
loopを使い、breakのチェックを最後に置きます。
理解度チェック
Section titled “理解度チェック”理解度チェック
1. while ループが無限ループになってしまう典型的な間違いはどれですか?
2. このページによると、loop より while を選ぶべきなのはどんなときですか?
3. 本体が必ず少なくとも1回実行されるループは、どう書きますか?
スコア: 0 / 3
さらに詳しく
Section titled “さらに詳しく”- whileで条件付きループ — The Rust Programming Language 日本語版:
whileとloopを比べながら紹介する公式の入門です。 - while — Rust By Example 日本語版:
whileループで書いたFizzBuzzを実行できます。 - Predicate loops — The Rust Reference(英語):
whileループがどう動くかの正確なルールです。 - The
whilekeyword — 標準ライブラリのドキュメント(英語):whileとwhile letを例付きで短くまとめています。