"cannot move a value of type FnOnce" 移动盒装函数时
"cannot move a value of type FnOnce" when moving a boxed function
我正在尝试用 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
中,我原以为这样可以解决编译器不知道大小的问题。我怎样才能编译上面的程序?
这是 FnOnce
特征的定义(稍微简化了一点):
pub trait FnOnce<Args> {
type Output;
fn call_once(self, args: Args) -> Self::Output;
}
要调用 FnOnce
闭包,您需要能够将闭包值本身移动到调用中。请注意 self
必须是 actual 闭包类型; Box<dyn FnOnce>
是完全不同的类型。
Rust 1.35
Box<dyn FnOnce>
现在可以调用了;您的原始代码按原样工作。
以前的版本
标准库中是一种类型来解决这种情况:FnBox
。 可惜,不稳定
您的替代选择是:
- 重构代码,以便保留 实际 闭包类型而不是
Box<FnOnce>
。
- 改用
Box<FnMut>
。
- 等待
FnBox
稳定。
- 切换到夜间编译器。
FnBox
不太可能变得稳定,但目前您可以将 F: FnOnce(...) -> ...
包装在 Option<F>
中,将其绑定在可变闭包中,然后解包并在内部调用它(所以如果它被调用不止一次,它就会恐慌);生成的闭包可以装箱为 Box<FnMut(...) -> ...>
,您可能希望以某种方式包装它以确保它只被使用 ("called") 一次。
查看(我的)boxfnonce
箱子。
我正在尝试用 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
中,我原以为这样可以解决编译器不知道大小的问题。我怎样才能编译上面的程序?
这是 FnOnce
特征的定义(稍微简化了一点):
pub trait FnOnce<Args> {
type Output;
fn call_once(self, args: Args) -> Self::Output;
}
要调用 FnOnce
闭包,您需要能够将闭包值本身移动到调用中。请注意 self
必须是 actual 闭包类型; Box<dyn FnOnce>
是完全不同的类型。
Rust 1.35
Box<dyn FnOnce>
现在可以调用了;您的原始代码按原样工作。
以前的版本
标准库中是一种类型来解决这种情况:FnBox
。 可惜,不稳定
您的替代选择是:
- 重构代码,以便保留 实际 闭包类型而不是
Box<FnOnce>
。 - 改用
Box<FnMut>
。 - 等待
FnBox
稳定。 - 切换到夜间编译器。
FnBox
不太可能变得稳定,但目前您可以将 F: FnOnce(...) -> ...
包装在 Option<F>
中,将其绑定在可变闭包中,然后解包并在内部调用它(所以如果它被调用不止一次,它就会恐慌);生成的闭包可以装箱为 Box<FnMut(...) -> ...>
,您可能希望以某种方式包装它以确保它只被使用 ("called") 一次。
查看(我的)boxfnonce
箱子。