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

时间:2018-03-07 03:46:39

标签: 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;
            }
        }
    }
}

2 个答案:

答案 0 :(得分:6)

最简单的方法就是使用不涉及任何长期借款的指数:

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;
        }
    }
}

如果你真的,真的想要使用迭代器,你可以通过将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);
    }
}

答案 1 :(得分:0)

如果您可以修改v的类型类型,并且v的元素为Copy,则可以将MyStruct包裹在Cell中。

#[derive(Copy, Clone)] 
struct MyStruct {
    a: i32,
}

fn main() {
    use std::cell::Cell;
    let v = vec![
        Cell::new(MyStruct { a: 1 }),
        Cell::new(MyStruct { a: 2 }),
        Cell::new(MyStruct { a: 3 }),
    ];

    for elem in v.iter() {
        for other_elem in v.iter() {
            let mut e = elem.get();
            if other_elem.get().a > e.a {
                e.a += 1;
                elem.set(e);
            }
        }
    }
}

如果相反,您将&mut传递给切片(或可以转换为切片的&mut),请使用Cell::from_mutCell::as_slice_of_cells并使用与上述相同的技巧(假设切片为Copy)。