【Rust入門】繰り返し処理(for, while, loop)を分かりやすく解説

Rust における 繰り返し処理(for, while, loop)の基本について初心者にも分かりやすく解説します。
Rust の繰り返し処理
プログラミングでは、繰り返し処理(ループ)は、複数回の処理を効率よく実行したいときに欠かせないものです。Rustには主に、for、while、loop といった3種類のループ構文があります。
この記事では、それぞれの繰り返し処理の使い方の基本について紹介していきます。
for による繰り返し処理
for の基本構文
Rust の for 文の基本構文は以下のようになります。
for の基本構文for 要素 in イテレータ {
// 繰り返したい処理
}Rust の for ループは、C/C++ 等の多くの言語のようにインデックスを増やしていき繰り返すのではなく、イテレータによって制御されることが特徴です。Python に触れたことがある方はなじみがある方法です。
ここでいう「イテレータ」とは、繰り返し可能なシーケンスを表すオブジェクトで、for はその要素を1つずつ取り出して処理をしていきます。例えば、数値の範囲(0..5)や、配列・ベクタ(Vec<T>)などのコレクションはイテレータとして扱うことができます。
私自身、以前は C/C++ や Java といったインデックスベースの for ループに慣れていたため、最初にイテレータベースの Python に触れたときは少し違和感を感じました。しかし、慣れてくるとインデックス管理のわずらわしさがなく、構文もすっきりしていてとても合理的だと感じるようになりました。Rust についても同様のイテレータベースの for を採用しているため、最初は戸惑うかもしれませんが一度仕組みを理解すれば安全性と可読性を両立できる強力な構文だと分かると思います。
数値の範囲による繰り返し
以下の簡単な例で for の使い方を見ていきましょう。
fn main() {
// forによる繰り返し
for i in 0..5 {
println!("i = {}", i);
}
}i = 0 i = 1 i = 2 i = 3 i = 4
上記例では、i に 0 から 4 までの値を順に取り出し、順に表示していきます。
0..5 は、「0 以上 5 未満」のイテレータを表します。なお、末尾の数値は含まれません。末尾の数値を含みたい場合は 0..=5 とすることで「0 以上 5 以下」となります。
配列やベクタ(Vec<T>)を使った繰り返し
配列やベクタ(Vec<T>)を使ったfor文の繰り返し例についても見ておきましょう。
配列の場合
fn main() {
let num_array = [2, 4, 5];
// forによる繰り返し(配列を使う場合)
for num in num_array {
println!("{}", num);
}
}【実行結果】 2 4 5
ベクタ(Vec<T>)の場合
fn main() {
let fruits = vec!["apple".to_string(), "banana".to_string(), "blueberry".to_string()];
// forによる繰り返し (Vec で参照のみ)
for fruit in &fruits {
println!("{}", fruit);
}
}【実行結果】 apple banana blueberry
いずれの例も配列やベクタの先頭から順に要素を取り出し表示しています。なお、Vec の例は不変参照を渡していますが、変更が必要な場合には以下のように可変参照を使います。
fn main() {
let mut fruits = vec!["apple".to_string(), "banana".to_string(), "blueberry".to_string()];
// forによる繰り返し (Vec で変更を伴う)
for fruit in &mut fruits {
fruit.push_str("_add");
println!("{}", fruit);
}
}【実行結果】 apple_add banana_add blueberry_add
また、変数をそのまま渡すと所有権が移動します。
fn main() {
let fruits = vec!["apple".to_string(), "banana".to_string(), "blueberry".to_string()];
// forによる繰り返し (Vec で所有権の移動を伴う)
for fruit in fruits {
println!("{}", fruit);
}
// 所有権が移動するので以下はエラーとなる
// println!("{:?}", fruits);
}上記の場合、所有権が移動するためコメントアウトしている println はエラーとなります。この方法は、ループ後に元の Vec を使わない場合や大きなサイズの Vec のためループ終了にあわせてメモリを解放したい場合などに利用できます。
break/continue による繰り返しの制御
繰り返しの最中には一定の条件になった場合には、繰り返し処理を終了したり、後続の処理をスキップしたりしたい場合があります。その際には break 文や continue 文を使用します。なお、以降で紹介する while や loop でも使用できるのでここで紹介しておきます。
break:ループを終了するcontinue:後続の処理を実施せずに次の繰り返しにスキップする
以下の例は、0..10 の数値シーケンスを表示していくのですが、i が 2の時はスキップし、i が 5 になったらループを終了するような例です。
fn main() {
// break, continue による繰り返しの制御
for i in 0..10 {
if i == 2 {
continue; // 後続の処理をスキップ
}
if i == 5 {
break; // ループを終了して抜ける
}
println!("i = {}", i);
}
}【実行結果】 i = 0 i = 1 i = 3 i = 4
出力結果を見ると i = 2 はスキップされており、i = 5 の際にはループを抜けるため 5 以降の数字は表示されていないことが分かります。
while による繰り返し処理
while の基本構文
Rust の while 文の基本構文は以下のようになります。
while の基本構文while 条件 {
// 条件がtrueの間、処理を繰り返す
}while ループは、条件が満たされている限り繰り返す構文です。ループの回数が決まっていないときや、外部の変数、関数の結果などに応じて繰り返すような場面でよく使用します。
例えば以下の例では、数字が5になるまで表示を繰り返します。
fn main() {
let mut n = 1;
// whileによる繰り返し
while n <= 5 {
println!("n = {}", n);
n += 1;
}
println!("終了");
}【実行結果】 n = 1 n = 2 n = 3 n = 4 n = 5 終了
loop による繰り返し処理
loop の基本構文
Rust の loop 文の基本構文は以下のようになります。
loop の基本構文loop {
// 明示的に break するまで無限ループで繰り返す
}loop は、無限ループを意図的に書く構文です。他の多くの言語には存在しない Rust 特有の明示的な無限ループです。break を使用して自分でループの終了タイミングを制御する必要があります。
基本的な loop の使用方法
以下の例で loop の基本的な使用方法を見てみましょう。
fn main() {
let mut count = 0;
// loopによる無限ループ (breakが必要)
loop {
// 5以上の場合、ループを終了する
if count >= 5 {
break;
}
println!("count = {}", count);
count += 1;
}
}【実行結果】 count = 0 count = 1 count = 2 count = 3 count = 4
上記の例では、count を増やしつつ 5 以上の条件に一致したら break で繰り返しを終了します。loop の処理では無限ループであるため、break を記載しないと処理が終わらないことに注意して使用してください。
loop の値の返却
他の for や while による繰り返しとは異なり、loop だけが break によって値を返すことができます。
以下の例では、上記の処理と同じですが処理結果を返却しています。
fn main() {
let mut count = 0;
// loopのbreak時に値を返却する
let result = loop {
if count >= 5 {
break true;
}
println!("count = {}", count);
count += 1;
};
println!("result : {}", result);
}【実行結果】 count = 0 count = 1 count = 2 count = 3 count = 4 result : true
値を返却する際には「break 値;」のように記載します。while や for のループでは、break に値を指定することはできませんので注意してください。
while による無限ループよりも loop を使用する
無限ループは、以下のように while で書き換えることができます。
while true {
// 無限ループの処理
}ただし、Rustでは while true よりも loop を使用することが一般的であり、コンパイル時には以下のような警告でアドバイスをしてくれます。(※旧バージョンだと表示されない可能性があります)
warning: denote infinite loops with `loop { ... }`
|
5 | while true {
| ^^^^^^^^^^ help: use `loop`
|理由は、loop は無限ループだという意図が一目でわかることがあげられます。loop は無限ループを明示するための専用構文であるため、読みやすさだけでなく break を書く必要があることが明確で、場合によって値を返すこともできるという柔軟さも持ち合わせています。
そのため、Rustでは「無限ループ = loop」と覚えておくとよいでしょう。
まとめ
この記事では、Rust における繰り返し処理の基本として、for、while、loop の3つの構文について解説しました。
forはイテレータベースのループで、安全かつ簡潔にコレクションを処理できます。whileは条件が満たされている間だけ繰り返す処理に適しており、状態に基づくループに便利です。loopは明示的な無限ループを実現でき、breakによってループを抜けるだけでなく、値を返すこともできる柔軟な構文です。
Rustのループ構文は、所有権や安全性といったRustの特徴を踏まえた設計になっており、最初は戸惑う部分もあるかもしれませんが、使い方に慣れることで安全かつ効率的なコードを書くことができるようになります。
繰り返し処理はあらゆるプログラムで登場する重要な要素ですので、基本をしっかり身につけていただけたらと思います。







