我正在尝试用 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闭合类型; ABox<dyn FnOnce>
是完全不同的类型。
铁锈1.35 https://blog.rust-lang.org/2019/05/23/Rust-1.35.0.html#fn-closure-traits-implemented-for-boxdyn-fn
Box<dyn FnOnce>
现在可以被调用;您的原始代码按原样工作。
之前的版本
There is标准库中用于解决这种情况的类型:FnBox http://doc.rust-lang.org/std/boxed/trait.FnBox.html. 很遗憾,不稳定。
您的替代选择是:
- 重构代码,以便代替
Box<FnOnce>
,你保留actual闭合类型。
- Use
Box<FnMut>
反而。
- 等待
FnBox
稳定下来。
- 切换到夜间编译器。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)