gpt4 book ai didi

rust - 闭包是 `FnOnce`,因为它将变量 `________` 移出其环境

转载 作者:行者123 更新时间:2023-12-04 01:02:42 33 4
gpt4 key购买 nike

我在将引用计数变量移动到需要实现的闭包中遇到了一些问题 FnMut .
以下代码工作正常:

use std::rc::Rc;

fn main() {
let callback;

let data: Rc<Vec<f32>> = Rc::new(Vec::new());

{
let data = data.clone();

callback = move || {
data.iter().for_each(|v| println!("{}", v));
};

consumer(callback);
}
}

fn consumer<D>(callback: D)
where
D: FnMut(),
{
}
如果我将关闭更改为:
callback = move || {
data;
};
编译器产生错误:
  --> src/test1.rs:11:20
|
11 | callback = move || {
| ^^^^^^^ this closure implements `FnOnce`, not `FnMut`
12 | data;
| ---- closure is `FnOnce` because it moves the variable `data` out of its environment
...
15 | consumer(callback);
| -------- the requirement to implement `FnMut` derives from here
这个例子有效:
callback = move || {
let x = data[0];
println!("{}", x);
};
这个例子没有:
callback = move || {
let x = data;
println!("{}", x[0]);
};
let data: Arc<Mutex<Vec<f32>>> = Arc::new(Mutex::new(Vec::new())); ,这有效:
callback = move || {
let x = data.lock().unwrap();
};
这不会:
callback = move || {
let x = data;
};
这背后的原因是什么?

最佳答案

The following code works fine:

let data: Rc<Vec<f32>> = Rc::new(Vec::new());
{
let data = data.clone();
callback = move || {
data.iter().for_each(|v| println!("{}", v));
};

首先,在构造闭包时, data移入其中,因为闭包声明为 move || .这就是为什么要使用 data 需要事先克隆的原因。再次在关闭之外
然后,当闭包被调用时, iter() is a method that takes &self , 所以 data不被方法调用移出;它是借来的,闭包仍然拥有它。因此,可以根据需要多次调用闭包——它会自动实现 Fn而不仅仅是 FnOnce .
callback = move || {
data;
};

callback = move || {
let x = data;
println!("{}", x[0]);
};

在这里,当闭包被调用时, data被移动(按值使用,而不是按引用)。在第一种情况下,它立即被丢弃;在第二个中,它被移动到局部变量 x 中。 .
如果一个值被移出一个闭包,那么这个闭包只实现了 FnOnce , 并且只能被调用一次,因为如果闭包被第二次调用,它就没有那个值可以再使用了。
一般来说,任何对变量名称的简单提及都是一种举动。 其他一切都是一个特定的异常(exception):
  • 如果该值实现了 Copy trait 那么它可以是一个副本而不是一个移动,这意味着原始保持有效。 (这里不适用,因为 Rc 没有实现 Copy 。)
  • 如果调用诸如 .iter() 之类的方法或 .lock() ,方法可以取&self&mut self ; Rust 会自动接受一个引用,就像你写了 (&data).iter() 一样反而。
  • println!是一个宏,为方便起见,它隐式引用其参数。

  • 如果你写 &data;let x = &data;相反,您将创建一个引用,它不会移动原始值。

    关于rust - 闭包是 `FnOnce`,因为它将变量 `________` 移出其环境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67696784/

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