fn make_adder(x: String) -> Box<Fn() -> String> {
Box::new(|| x)
}
fn main() {
make_adder(String::from("a"));
}
Run Code Online (Sandbox Code Playgroud)
这导致此错误:
fn make_adder(x: String) -> Box<Fn() -> String> {
Box::new(|| x)
}
fn main() {
make_adder(String::from("a"));
}
Run Code Online (Sandbox Code Playgroud)
我该如何纠正?
可以多次调用实现的闭包(接收器参数为,对闭包的不变引用):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);
}
Run Code Online (Sandbox Code Playgroud)
这意味着通过您的闭包Fn() -> String,您可以执行以下操作:
let s1 = adder();
let s2 = adder();
Run Code Online (Sandbox Code Playgroud)
现在您将只有两个,String尽管只有一个!魔法?您当然可以通过克隆原始字符串来获取另一个字符串,但是我们在这里不这样做。因此,它显然无法正常工作。
您可以通过两种方式解决该问题。您不需要多次调用闭包。在这种情况下,您可以简单地更改Fn为FnOnce(要求较低的特征)。一个FnOnce封闭只能叫......嗯......一次。这有效:
fn make_adder(x: String) -> Box<FnOnce() -> String> {
Box::new(|| x)
}
Run Code Online (Sandbox Code Playgroud)
另一方面,也许您希望多次调用闭包,并且始终希望返回字符串的新克隆。您可以这样做:
fn make_adder(x: String) -> Box<Fn() -> String> {
Box::new(move || x.clone())
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们添加了一个.clone()调用(因为在Rust中,深度克隆永远不会隐式!),并且添加了move关键字。后者是将字符串显式移动x到闭包中所必需的,而不仅仅是借用它。
| 归档时间: |
|
| 查看次数: |
1193 次 |
| 最近记录: |