有效地改变矢量,同时也迭代相同的矢量

and*_*man 3 rust

我有一个结构向量,我将向量中的每个元素与其他每个元素进行比较,并在某些情况下改变当前元素.

我的问题是你不能同时发生可变和不可变的借位,但是我不知道如何重新解决我的问题以解决这个问题而不克隆当前元素或整个向量,这看起来像因为我只是在改变当前元素,所以不需要与自身进行比较(我跳过这种情况).

我确信在Rust中有一种惯用的方法.

struct MyStruct {
    a: i32,
}

fn main() {
    let mut v = vec![MyStruct { a: 1 }, MyStruct { a: 2 }, MyStruct { a: 3 }];

    for elem in v.iter_mut() {
        for other_elem in v.iter() {
            if other_elem.a > elem.a {
                elem.a += 1;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

DK.*_*DK. 7

最简单的方法是使用索引,这些索引不涉及任何长期借用:

for i in 0..v.len() {
    for j in 0..v.len() {
        if i == j { continue; }
        if v[j].a > v[i].a {
            v[i].a += 1;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你真的真的想要使用迭代器,你可以通过将它们Vec分成不相交的切片来实现:

fn process(elem: &mut MyStruct, other: &MyStruct) {
    if other.a > elem.a {
        elem.a += 1;
    }
}

for i in 0..v.len() {
    let (left, mid_right) = v.split_at_mut(i);
    let (mid, right) = mid_right.split_at_mut(1);
    let elem = &mut mid[0];

    for other in left {
        process(elem, other);
    }
    for other in right {
        process(elem, other);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @JosephGarvin,您可以改变元素,但不能同时拥有共享引用和可变引用。考虑一下您的向量 (v1) 是否包含向量 (v2),并且您同时使用 iter() 和 iter_mut() 迭代 v1。您将拥有 v2 的 &mut 和 &。现在考虑通过 & 你得到 v2 的第一个元素,然后通过 &mut 将 vec 的大小调整为 0。第一个元素的 & 现在指向无效内存。 (2认同)