我试图在Rust中进行一些高阶编程,但是我在处理闭包时遇到了一些困难。这是一个代码片段,说明了我遇到的一个问题:
pub enum Foo {
Bar(Box<FnOnce(i32)>),
}
pub fn app(i: i32, arg: Foo) {
match arg {
Foo::Bar(f) => f(i),
}
}
当我编译这段代码时,我收到以下错误消息:
error[E0161]: cannot move a value of type std::ops::FnOnce(i32) + 'static: the size of std::ops::FnOnce(i32) + 'static cannot be statically determined
--> src/main.rs:7:24
|
7 | Foo::Bar(f) => f(i),
| ^
由于我将函数放在Box
中,我原以为这会解决编译器不知道大小的问题。如何编译上述程序?
答案 0 :(得分:14)
这是FnOnce
特征的定义(简化了一点):
pub trait FnOnce<Args> {
type Output;
fn call_once(self, args: Args) -> Self::Output;
}
要调用FnOnce
闭包,您需要能够将闭包值本身移动到调用中。请注意,self
必须是实际闭包类型; Box<dyn FnOnce>
完全是另一种类型。
Box<dyn FnOnce>
;您的原始代码按原样运行。
是标准库中的一种类型,用于解决这种情况:FnBox
。 不幸的是,它不稳定。
您的替代选择是:
Box<FnOnce>
。Box<FnMut>
。FnBox
稳定。答案 1 :(得分:1)