gpt4 book ai didi

rust - 为什么 Rust 无法识别我在闭包内重新分配给移动的变量?

转载 作者:行者123 更新时间:2023-11-29 08:03:47 24 4
gpt4 key购买 nike

我无法理解为什么特定模式无法编译。

当我移动一个变量然后在闭包之外重新分配给它时,Rust 可以识别,我认为正确地允许代码编译,但是当我尝试在一个将运行多次的闭包中执行相同的操作时,它不会.

fn main() {
let mut v = vec![1, 2, 3, 4];
v.into_iter().fold(0, |a, b| a + b);
v = vec![1, 2, 3, 4];
vec![1, 2, 3].into_iter().for_each(|x| {
v.into_iter().fold(x, |a, b| a + b);
v = vec![1, 2, 3, 4];
});
}
error[E0507]: cannot move out of captured outer variable in an `FnMut` closure
--> src/main.rs:6:9
|
2 | let mut v = vec![1, 2, 3, 4];
| ----- captured outer variable
...
6 | v.into_iter().fold(x, |a, b| a + b);
| ^ cannot move out of captured outer variable in an `FnMut` closure

在我看来,对 v 的重新分配应该满足借用检查器的要求,即在移动后不会访问任何变量。我错过了什么吗?

最佳答案

正如@Shepmaster 提到的,解决方法是使用std::mem::replace

那么,有什么区别:

    v.into_iter().fold(x, |a, b| a + b);
v = vec![1, 2, 3, 4];

和:

    let v_old = std::mem::replace(&mut v, vec![1, 2, 3, 4]);
v_old.into_iter().fold(x, |a, b| a + b);

?

两个词:异常安全

如果由于某种原因,表达式 v.into_iter().fold(...) 会崩溃,它会离开 v 并移出下一个语句永远不会被执行。

这在 FnOnce 中是完全可以接受的,因为您再也不会调用闭包,但在 FnMutFn 中是 Not Acceptable 在下一次电话 session 上...你会用 v 做什么?

另一方面,使用 std::mem::replace,您交换 firstthen 执行潜在的 panicing 操作。如果操作确实发生 panic ,那么剩下的“移出”就是一个临时变量,它无论如何都会在堆栈帧的末尾消失。没问题。

关于rust - 为什么 Rust 无法识别我在闭包内重新分配给移动的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47686318/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com