Iteratorトレイト
nextと遅延評価
「Iteratorトレイト」はCoddyKit上の無料Learn Rust Codingレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn Rust Coding学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn Rust Codingコースには全4レッスンが含まれています。
イテレーターとは
イテレーターとは、値の列を1つずつ生成するものです。Rustでは、ベクター、範囲、スライスなどのコレクションを処理する慣用的な方法です。
この仕組み全体は、1つのトレイトIteratorを基盤としています。型がこれを実装すると、多数の便利なメソッドをすぐに使えるようになります。
Iteratorトレイト
Iteratorトレイトには、必須メソッドnextと関連型Itemが1つずつあります:
type Item— 生成される値の種類fn next(&mut self) -> Option<Self::Item>— 次の値を返す
値が残っている間はSome(value)を返し、完了するとNoneを返します。
fn main() {
let v = vec![10, 20, 30];
let mut it = v.iter();
println!("{:?}", it.next());
println!("{:?}", it.next());
println!("{:?}", it.next());
println!("{:?}", it.next());
}nextはOptionを返す
nextを呼び出すたびにイテレーターが進み、Optionが返されます。Someは実際の値を包み、Noneは終端を示します。
nextが&mut selfを受け取ることに注目してください。呼び出すと内部状態が変化するため、次の呼び出しでは別の値が返されます。
fn main() {
let mut it = (1..4).into_iter();
while let Some(n) = it.next() {
println!("got {}", n);
}
println!("done");
}イテレーターは遅延評価される
イテレーターを作成しただけでは、何も起こりません。値を要求するものが現れるまで、値は計算されません。これを遅延評価と呼びます。
次の例では、イテレーターを消費していないため、mapのクロージャーは一度も実行されません。
fn main() {
let nums = vec![1, 2, 3];
let _doubled = nums.iter().map(|x| {
println!("mapping {}", x);
x * 2
});
println!("nothing printed above this line");
}消費すると処理が実行される
遅延イテレーターを実際に実行するには、イテレーターを消費します。forループは最も単純なコンシューマーで、Noneが返るまでnextを繰り返し呼び出します。
これで、同じmapのクロージャーが各要素に対して実行されます。
fn main() {
let nums = vec![1, 2, 3];
for x in nums.iter().map(|x| x * 2) {
println!("value {}", x);
}
}反復処理の3つの方法
コレクションには、イテレーターを生成する3つのメソッドがあります:
iter()—&Tを生成する(借用)iter_mut()—&mut Tを生成する(可変借用)into_iter()—Tを生成する(所有権を取得)
fn main() {
let mut v = vec![1, 2, 3];
for x in v.iter_mut() {
*x += 10;
}
println!("{:?}", v);
}forループはinto_iterを使う
for x in collectionのように直接記述すると、Rustはinto_iter()を呼び出してコレクションを消費します。
このループの後では、vはイテレーターにムーブされているため、再び使用できません。
fn main() {
let v = vec![String::from("a"), String::from("b")];
for s in v {
println!("{}", s);
}
// v is no longer usable here
}範囲はイテレーター
0..5のような範囲自体が、0, 1, 2, 3, 4を生成するイテレーターです。終了位置は含まれません。両端を含む範囲には0..=5を使います。
範囲は、手動でインデックスを管理せずにカウントするループを書くのに適しています。
fn main() {
for i in 0..5 {
print!("{} ", i);
}
println!();
for i in 1..=3 {
print!("{} ", i);
}
println!();
}count:単純なコンシューマー
countはイテレーター全体を消費し、生成された要素数を返します。これは多数ある消費アダプターの1つです。
消費するため、その後でイテレーターを再利用することはできません。
fn main() {
let total = (1..=100).count();
println!("there are {} numbers", total);
}sum:1つの値に畳み込む
sumはすべての要素を合計し、単一の値を返します。Rustが生成すべき型を認識できるよう、対象の型を注釈することがよくあります。
手動でアキュムレータを使うループよりも、簡潔で分かりやすくなります。
fn main() {
let total: i32 = (1..=5).sum();
println!("sum is {}", total);
}イテレータが重要な理由
イテレータを使うと合成可能性が得られます。小さな操作をつないで、分かりやすいパイプラインを構築できます。またゼロコストです。コンパイラが最適化するため、手書きのループと同じくらい高速に実行されます。
next、遅延評価、消費を理解することが、この先のすべての基礎になります。
クイックチェック
Iteratorトレイトについての理解度を確認しましょう。
まとめ
Rustのイテレータの基本を学びました。
Iteratorトレイトに必要なのは、nextとItem型だけですnextはSome(value)を返し、その後Noneを返します- イテレータは遅延評価され、消費されるまで何もしません
iter、iter_mut、into_iterによって、借用と所有権の扱いを制御できますfor、count、sumなどのコンシューマが処理を実行します
よくある質問
「Iteratorトレイト」レッスンは無料ですか?
はい。「Iteratorトレイト」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn Rust Codingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn Rust Codingコースには全4レッスンが含まれています。
「Iteratorトレイト」で何を学びますか?
nextと遅延評価 ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Learn Rust Codingを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLearn Rust Codingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「Iteratorトレイト」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLearn Rust Codingレッスンでコードを書いて実行できますか?
はい。すべてのLearn Rust Codingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Iteratorトレイト
- map、filter、collect
- アダプターとコンシューマー
- カスタムイテレーター