/*
Rust の take_while の使い方・処理概要・振る舞い
そして「take_while と next は並列で動くのか?」の説明を
すべて 1 つのコードブロック内にまとめる。
【✔ take_while とは何か】
take_while は Iterator / Stream に対して使えるメソッドで、
「与えた条件が true の間だけ、要素を取り出し続ける」
という挙動をする。
条件が false になった瞬間、
そのストリーム(またはイテレータ)は終了する。
【✔ 基本使用例 (Iterator)】
use std::iter;
let v = vec![1, 2, 3, 4, 5];
let mut it = v.into_iter().take_while(|x| *x < 4);
assert_eq!(it.next(), Some(1)); // 条件 true
assert_eq!(it.next(), Some(2)); // 条件 true
assert_eq!(it.next(), Some(3)); // 条件 true
assert_eq!(it.next(), None); // 4 は条件 false のためここで終了
【✔ Stream 版の take_while (futures::StreamExt)】
use futures::{StreamExt};
let s = futures::stream::iter([10, 20, 30, 40, 50]);
let mut s2 = s.take_while(|x| futures::future::ready(*x < 40));
assert_eq!(s2.next().await, Some(10));
assert_eq!(s2.next().await, Some(20));
assert_eq!(s2.next().await, Some(30));
assert_eq!(s2.next().await, None); // 40 で終了
【✔ take_while の処理の流れ】
- next() が呼ばれる
- 内部で元のストリーム/イテレータの next() を呼ぶ
- 得られた値を条件関数に渡す
- 条件が true → 値を返す
- 条件が false → 以降はすべて終了 (None) を返す
※「条件 false → 1 回で完全停止」というのが take_while の最大の特徴
【✔ take_while と next は “並列” に動くのか?】
結論:並列ではない(= 同時には動かない)。
理由:
- Iterator 版の next() は同期処理なのでそもそも並列になりようがない
- Stream 版でも、next().await を呼んだ瞬間に
take_while の内部がその都度進むだけで、
並列実行されるわけではない - Rust の Stream は「pull 型」なので、
next().await を呼び出すまで進まないし動かない
つまり:
「next を呼ぶ → take_while の内部処理が実行される」
という順番で逐次処理される。
【✔ 並列で動くと誤解されやすい理由】
take_while が “入力ストリームを監視している” ように見えるため。
しかし実際には:
- ストリーム側が勝手に進むことはない
- next().await を呼んだ時だけ、1 ステップだけ処理が進む
つまり pull モデルによる逐次実行であり、
並列処理はしていない。
【✔ まとめ】
● take_while は「条件が false になるまで要素を返す」フィルタ
● false が出た瞬間に完全停止
● next() と並列ではなく、next() を呼ぶごとに 1 ステップ進むだけ
● Iterator でも Stream でも振る舞いは同じ(非同期かどうかだけ違う)
*/