ループ(Loops)とイテレータ(Iterators)の選択は、Rustにおける非常に重要なトピックの一つです。Rustはシステムプログラミング言語であり、その設計理念の中でメモリの安全性や効率性が非常に重視されています。特にループとイテレータの使い方には違いがあり、それぞれが特定のシナリオにおいて有利に働く場合があります。本記事では、Rustにおけるループとイテレータの違い、選択基準、そしてそれぞれの利点について詳しく解説します。
1. ループ(Loops)とは?
Rustのループは、基本的に指定した条件が満たされる限り繰り返し実行される構造です。Rustでは、loop
、for
、while
という3種類のループ構文が用意されています。

1.1 loop
loop
は無限ループを作成するためのキーワードです。このループは明示的に終了条件を指定しない限り永遠に繰り返し実行されます。例えば、以下のコードは無限ループです。
rustloop {
println!("このループは無限に続きます");
}
このループを終了させるためには、break
文を使用して手動でループを抜ける必要があります。
1.2 for
for
ループは、イテラブルなコレクション(配列、ベクター、範囲など)を反復処理する際に使用されます。Rustのfor
ループは、コレクションの各要素に対して自動的にイテレートします。以下は、範囲を用いたfor
ループの例です。
rustfor i in 1..5 {
println!("{}", i); // 1, 2, 3, 4 が順に出力される
}
この例では、1..5
の範囲を使って、1
から4
までの数値を出力します。for
ループはRustの最も使われるループの一つで、シンプルで効率的です。
1.3 while
while
ループは、指定された条件がtrue
である限り実行され続けます。条件がfalse
になると、ループは終了します。以下は、while
ループの例です。
rustlet mut count = 0;
while count < 5 {
println!("{}", count); // 0, 1, 2, 3, 4 が順に出力される
count += 1;
}
while
ループは、条件を手動で変更する必要があり、繰り返し処理の制御が柔軟になります。
2. イテレータ(Iterators)とは?
イテレータは、コレクションの各要素を順番に取得するための抽象的な方法です。Rustでは、イテレータは非常に強力で、Iterator
トレイトを実装することで、コレクションに対する操作を柔軟に行うことができます。イテレータは、for
ループ内部で使われることが多いですが、イテレータ自体を明示的に操作することも可能です。
2.1 イテレータの基本
Rustでは、イテレータを使ってコレクションを反復処理することができます。たとえば、iter()
メソッドを使ってベクターのイテレータを取得し、それをfor
ループで使うことができます。
rustlet vec = vec![1, 2, 3, 4, 5];
for num in vec.iter() {
println!("{}", num); // 1, 2, 3, 4, 5 が順に出力される
}
この場合、iter()
メソッドは、ベクターの各要素を参照するイテレータを返します。
2.2 イテレータのチェーン
イテレータはその後の操作をチェーン(連結)することができ、複雑な操作を一行で表現することができます。例えば、map()
やfilter()
などを使って、イテレータの結果を変換したり、フィルタリングしたりすることができます。
rustlet numbers = vec![1, 2, 3, 4, 5];
let result: Vec<i32> = numbers.iter()
.map(|&x| x * 2)
.filter(|&x| x > 5)
.collect();
println!("{:?}", result); // [6, 8, 10] が出力される
この例では、map()
で各要素を2倍にし、その後filter()
で5より大きい値だけを残しています。
3. ループとイテレータの使い分け
では、どのような場面でループとイテレータを使い分けるべきなのでしょうか?
3.1 ループの使用が適している場合
- 簡単な反復処理:反復処理が単純で、特にコレクションの操作がない場合は、
loop
やwhile
を使用した方がシンプルでわかりやすいです。 - 明示的な終了条件:ループを終了させる条件が動的である場合や、終了するタイミングを柔軟に制御したい場合には、
loop
やwhile
が有効です。
3.2 イテレータの使用が適している場合
- コレクションの反復処理:イテレータはコレクションに対して非常に効率的で、
for
ループと組み合わせて使うことで、コードが簡潔で読みやすくなります。 - 複雑な操作:
map()
、filter()
、fold()
などを使った複雑なデータ処理を行いたい場合は、イテレータの方がコードが短く、直感的です。 - 遅延評価:イテレータは遅延評価を行うため、メモリ使用量を最小限に抑えつつ、必要な処理を行うことができます。特に大きなデータセットを扱う場合に有効です。
4. まとめ
Rustにおけるループとイテレータは、それぞれ異なる用途に適しています。ループはシンプルな反復処理や動的な終了条件に適しており、イテレータはコレクションを効率的に操作したり、複雑なデータ処理を行ったりする際に非常に強力です。プログラムの性質や目的に応じて、どちらのアプローチを使用するかを選ぶことが大切です。