在 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
为了克服这个问题,我添加了 Rc
和 RefCell
的使用,以允许我迭代一个引用,同时仍然能够改变:
#[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![]
}
}
当您希望其他一些结构拥有您所引用的对象时,应该使用引用,但在这里您正在使用新数据构建新向量,因此您应该保留元素。
我在使用借用检查器和 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
为了克服这个问题,我添加了 Rc
和 RefCell
的使用,以允许我迭代一个引用,同时仍然能够改变:
#[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![]
}
}
当您希望其他一些结构拥有您所引用的对象时,应该使用引用,但在这里您正在使用新数据构建新向量,因此您应该保留元素。