

三角形状に1次元の配列をループし、全ての組み合わせに対して処理を行いたい場合、Javaでは以下のような物になると思います

[code]

    Foo[] data = ...;
    for(int i = 0; i < data.length(); i++) {
        for(int j = i + 1; j < data.length(); j++) {
            //いろいろdata[i]やdata[j]を使って計算
            data[i].bar += ...;
            data[j].bar += ...;
        }
    }
    
[/code]

これをRustでIteratorのみでやる方法はあるのでしょうか?  
以下のように内部ループで元の`iter`を変えないようにコピーを作れれば(元のデータはコピーせず参照)と考えていたのですが、それらしき関数が見当たらなかったので

[code]

    let mut data: Vec<Foo> = ...;
    let mut iter = data.iter_mut();
    while let Some(idata) = iter.next() {
         //内部ループでは外部ループで使う`iter`を消費しないようにしたい
        let mut inner_iter = iter.clone();
        for jdata in inner_iter {
            //いろいろidataやjdataを使って計算
            idata.bar += ...;
            jdata.bar += ...;
        }
    }
    
[/code]


CC BY-SA 3.0
2016-07-27T16:11:27.867
27895
2016-11-22T06:16:45.393
3974
question
rust
Rustで2重ループをIteratorのみで行う方法はありますか？


イミュータブル・イテレータ[`std::slice::Iter`](https://doc.rust-
lang.org/std/slice/struct.Iter.html)であれば`clone()`可能ですが、ミュータブル・イテレータ[`std::slice::IterMut`](https://doc.rust-
lang.org/std/slice/struct.IterMut.html)は`Clone`トレイトを実装しません。これはRust言語が掲げる安全性を達成するための、意図的な制約です。

Rust言語では、同一オブジェクトを指す複数個のミュータブル参照`&mut
T`の存在を許可しません。「指し先のオブジェクトを書き換える能力がある」という観点において、ミュータブル・イテレータはミュータブル参照と同等の能力を持ちますから、ミュータブル・イテレータを複製することは出来ません。

素直にインデクス値ベースで実装するか、`RefCell`によるInterior
Mutabilityを利用することになります。後者はコンパイル時の所有権検査を実行時の検査に遅延させることに相当します。


CC BY-SA 3.0
2016-07-28T10:31:04.027
27915
2016-07-29T00:13:38.803
2016-07-29T00:13:38.803
49
49
27895
answer

[code]

    let mut a: Vec<i32> = (0..10).collect();
    for i in 1..a.len() {
        let (af, ae) = a.split_at_mut(i);
        for v in ae.iter_mut() {
            af[i - 1] += *v;
            *v += 1
        }
    }
    
[/code]

`split_at_mut`を使用して一つのmutableな配列を二つのmutableな配列に分けて参照することはできます。一つ目のforでindex使ってしまってるのでiteratorのみとはちょっと言えないですがｗ


CC BY-SA 3.0
2016-11-22T06:16:45.393
30590
2016-11-22T06:16:45.393
9572
27895
answer