在 for 循环中变异时借用错误

Borrowing errors whilst mutating in for loop

我在使用借用检查器和 rust 中的临时值时遇到问题。

我希望找到解决这个具体问题的方法,并更好地学习如何在未来处理这种情况。我最初从 for_each 开始,但 运行 遇到了提前终止的问题。

我考虑过将 check_foo 的逻辑移到 update_foo 中,但这对我的现实世界解决方案来说效果不佳; MRE 侧重于编译问题与我在整个程序中试图实现的目标。


编辑:有没有一种方法可以让我以纯函数式的方式实现这一点?


我想遍历 运行ge 个数字,更新 Vec<Foo> 并可能提前返回一个值。下面是我的代码的最小可重现示例,但有相同的错误:

我尝试实施为:

fn run<'a>(mut foos: Vec<Foo>) -> Vec<&'a u32> {
    let mut bar: Vec<&u32> = vec![];

    for num in 0..10 {
        for foo in &mut foos {
            update_foo(foo);

            let checked_foo = check_foo(&foo);
            if checked_foo.is_empty() {
                bar = checked_foo;
                break;
            }
        }
    }

    bar
}

/* `fn update_foo` and `fn check_foo` definitions same as below */

但这导致:

21 | for foo in &mut foos {
   |            ^^^^^^^^^ `foos` was mutably borrowed here in the previous iteration of the loop

为了克服这个问题,我添加了 RcRefCell 的使用,以允许我迭代一个引用,同时仍然能够改变:

#[derive(Clone, Debug, PartialEq)]
pub struct Foo {
    updated: bool,
}

fn run<'a>(foos: Vec<Rc<RefCell<Foo>>>) -> Vec<&'a u32> {
    let mut bar: Vec<&u32> = vec![];

    for num in 0..10 {
        for foo in &foos {
            update_foo(&mut foo.borrow_mut());

            let checked_foo = check_foo(&foo.borrow());
            if checked_foo.is_empty() {
                bar = checked_foo;
                break;
            }
        }
    }

    bar
}

fn update_foo(foo: &mut Foo) {
    foo.updated = true
}

fn check_foo(foo: &Foo) -> Vec<&u32> {
    if foo.updated {
        vec![&0, &1, &2]
    } else {
        vec![]
    }
}

这导致:

error[E0515]: cannot return value referencing temporary value
  --> src/main.rs:33:5
   |
26 |             let checked_foo = check_foo(&foo.borrow());
   |                                          ------------ temporary value created here
...
33 |     bar
   |     ^^^ returns a value referencing data owned by the current function

error[E0515]: cannot return value referencing function parameter `foos`
  --> src/main.rs:33:5
   |
23 |         for foo in &foos {
   |                    ----- `foos` is borrowed here
...
33 |     bar
   |     ^^^ returns a value referencing data owned by the current function

For more information about this error, try `rustc --explain E0515`.

我不完全确定你打算用它做什么,但在我看来,你正在使用的一些参考资料应该归我所有。这是我的想法。

#[derive(Clone, Debug, PartialEq)]
pub struct Foo {
    updated: bool,
}

fn run(foos: &mut Vec<Foo>) -> Vec<u32> {
    let mut bar: Vec<u32> = vec![];

    for num in 0..10 {
        for foo in foos.iter_mut() { 
            update_foo(foo);

            let checked_foo = check_foo(&foo);
            if checked_foo.is_empty() {
                bar = checked_foo;
                break;
            }
        }
    }

    bar
}

fn update_foo(foo: &mut Foo) {
    foo.updated = true
}

fn check_foo(foo: &Foo) -> Vec<u32> {
    if foo.updated {
        vec![0, 1, 2]
    } else {
        vec![]
    }
}

当您希望其他一些结构拥有您所引用的对象时,应该使用引用,但在这里您正在使用新数据构建新向量,因此您应该保留元素。