0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Rust] Iteratorは消費した後も巻き戻せる(場合が多い)

Posted at

Rust日本語公式ドキュメントのIteratorの解説を読むと、Iteratorは一度しか使えないというニュアンスを受ける。

つまり、このコードはイテレータを消費、または使い込むのです。 nextの各呼び出しは、イテレータの要素を一つ、食います。

食べたら無くなるということは、抽象的なイテレータを受け取る関数はそのイテレータを一度しか使えないと考えるかもしれない。しかしFilterやMapなどを多用しても要素がCloneトレイトを実装している場合はそのIteratorもclone()を呼び出せるため、clone()によりイテレーターを巻き戻すことができる。このことを利用して循環イテレーターを生成するcycle()などが実装されている。

以下に0から20までのRangeにMapを適用したイテレーターを受けとり、イテレーターを巻き戻しながら素数の倍数を出力する関数の例を示す

fn main() {
    reuse_iterator((0..20).map(|v| v as i32))
}
fn reuse_iterator(vec: impl Iterator<Item=i32> + Clone){
    for div in [3,5,7,11]{
        print!("multiple of {:>2} are",div);
        for i in vec.clone().filter(|v| {
            if (*v)%div==0{
                true
            }else{
                print!("* ");//イテレーターが怠惰であることを確認
                false
            }
        }){
            print!("{:>2}",i);
        }
        println!();
    }
}

出力

イテレーターが怠惰であること、イテレーターを消費した後もCloneにより再使用できていることを示す

multiple of  3 are 0* *  3* *  6* *  9* * 12* * 15* * 18* 
multiple of  5 are 0* * * *  5* * * * 10* * * * 15* * * * 
multiple of  7 are 0* * * * * *  7* * * * * * 14* * * * * 
multiple of 11 are 0* * * * * * * * * * 11* * * * * * * * 
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?