リストzipperを実装しようとしています。これまでのところ私が持っている:Rustでカスタムイテレータを実装する際の無限ループ
#[derive(RustcDecodable, RustcEncodable, Debug, Clone)]
pub struct ListZipper {
pub focus: Option<Tile>,
pub left: VecDeque<Tile>,
pub right: VecDeque<Tile>,
}
impl PartialEq for ListZipper {
fn eq(&self, other: &ListZipper) -> bool {
self.left == other.left && self.focus == other.focus && self.right == other.right
}
}
私は今、これは理にかなって私の頭では、イテレータ
impl Iterator for ListZipper {
type Item = Tile;
fn next(&mut self) -> Option<Tile> {
self.left.iter().chain(self.focus.iter()).chain(self.right.iter()).next().map(|w| *w)
}
}
を実装しようとしています。 ListZipper
を反復するときは、left
を繰り返し、次にfocus
を、さらにright
を反復したいとします。だから私はそれらの反復子を連鎖し、ちょうどnext()
を返します。
これは、ListZipper
のすべてのフィールドが空の場合に問題ありません。 1つが空でないとすぐにListZipper
を反復すると、無限ループになります。
問題はチェーンではありません。私がそれを例えばに置き換えると。 self.left.iter()
、およびleft
が空でない場合、問題は同じです。同様にfocus
およびright
についても同様である。
イテレータのすべての要素を印刷しようとしましたが、これは前面から背面に向かってVecDeque
を通過しているように見えます。私。 next()
は、カーソルが背面に到達したときにカーソルを前進させません。
なぜですか?
私はListZipper
自身がイテレータであることを望んでいないかもしれないが、それは別の議論です。
「次へ」は、それが正しく呼ばれるたびに完全な新しいイテレータを作成していることを理解していますか? – mcarton