gpt4 book ai didi

rust - 无法移出 Fn 闭包中捕获的外部变量

转载 作者:行者123 更新时间:2023-11-29 07:44:49 24 4
gpt4 key购买 nike

fn make_adder(x: String) -> Box<Fn() -> String> {
Box::new(|| x)
}

fn main() {
make_adder(String::from("a"));
}

这会导致此错误:

error[E0507]: cannot move out of captured outer variable in an `Fn` closure
--> src/main.rs:2:17
|
1 | fn make_adder(x: String) -> Box<Fn() -> String> {
| - captured outer variable
2 | Box::new(|| x)
| ^ cannot move out of captured outer variable in an `Fn` closure

我怎样才能让它正确?

最佳答案

实现 Fn 的闭包可以多次调用(接收参数为&self,闭包的不可变引用):

fn call_multiple_times<F: Fn(u8) -> i32>(f: F) {
// Works! We can call the closure mutliple times
let a = f(1);
let b = f(27);
let c = f(31);
}

这意味着使用闭包 Fn() -> String,您可以这样做:

let s1 = adder();
let s2 = adder();

现在您将拥有两个String,尽管您一开始只有一个!魔法? 您当然可以通过克隆原始字符串来获得另一个字符串,但我们在这里不这样做。所以这显然行不通。


您可以通过两种方式解决这个问题。要么你不需要多次调用你的闭包。在这种情况下,您只需将 Fn 更改为 FnOnce (要求不高的特征)。 FnOnce 闭包只能被调用……好吧……一次。这有效:

fn make_adder(x: String) -> Box<FnOnce() -> String> {
Box::new(|| x)
}

另一方面,也许您希望闭包被多次调用并且始终希望返回字符串的新克隆。你可以这样做:

fn make_adder(x: String) -> Box<Fn() -> String> {
Box::new(move || x.clone())
}

这里我们添加了一个 .clone() 调用(因为在 Rust 中,深度克隆永远不会隐式!)并且我们添加了 move 关键字。后者对于将字符串 x 显式移动到闭包中是必要的,而不仅仅是借用它。

关于rust - 无法移出 Fn 闭包中捕获的外部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50000453/

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