无法移出 Fn 闭包中捕获的外部变量 [英] Cannot move out of captured outer variable in an Fn closure
问题描述
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
,一个不可变的引用关闭):
A closure which implements Fn
can be called multiple times (the receiver parameter is &self
, an immutable reference to the closure):
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() ->字符串
,你可以这样做:
This means that with your closure Fn() -> String
, you could do this:
let s1 = adder();
let s2 = adder();
现在您将拥有两个 String
,尽管您只从一个开始!魔术?您当然可以通过克隆原始字符串来获得另一个字符串,但我们在这里不这样做.所以它显然行不通.
Now you would have two String
s although you only started with one! Magic? You can of course get another string by cloning the original string, but we don't do that here. So it clearly can't work.
您可以通过两种方式解决此问题.要么你不需要多次调用你的闭包.在这种情况下,您可以简单地将 Fn
更改为 FnOnce
(要求不高的特性).FnOnce
闭包只能被调用......好吧......一次.这有效:
You can fix that in two ways. Either you don't need your closure to be called multiple times. In that case you can simply change Fn
to FnOnce
(a less demanding trait). An FnOnce
closure can only be called ... well ... once. This works:
fn make_adder(x: String) -> Box<FnOnce() -> String> {
Box::new(|| x)
}
另一方面,也许你希望闭包被多次调用,并且总是希望返回一个新的字符串克隆.你可以这样做:
On the other hand, maybe you want the closure to be called multiple times and always want to return a new clone of the string. You can do that like this:
fn make_adder(x: String) -> Box<Fn() -> String> {
Box::new(move || x.clone())
}
这里我们添加了一个 .clone()
调用(因为在 Rust 中,深度克隆永远不会是隐式的!)并且我们添加了 move
关键字.后者对于将字符串 x
显式移动到闭包中是必要的,而不仅仅是借用它.
Here we added a .clone()
call (since in Rust, deep clones are never implicit!) and we added the move
keyword. The latter is necessary to explicitly move the string x
into the closure, not just borrow it.
这篇关于无法移出 Fn 闭包中捕获的外部变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!