特征界限不满足 [英] The trait bound is not satisfied
问题描述
这是我要调用的函数:
#[inline]
pub fn spawn<F>(f: F) -> Handle
where F: FnOnce(&mut Coroutine) + Send + 'static
{
Self::spawn_opts_impl(Box::new(f), Options::default())
}
然后我创建了一个枚举,因为我实际上想将它从一个线程发送到另一个线程,这也是我将函数装箱的原因.我也匹配了特征约束.
I then created an enum because I actually want to send it from one thread to another, which is also why I have boxed the function. I have also matched the trait constraints.
enum Message {
Task(Box<FnOnce(&mut Coroutine) + Send + 'static>),
}
但是如果我尝试从 Message
中提取函数:
But if I try to extract the function from a Message
:
fn main(){
let m = Message::Task(Box::new(|me| {
}));
let c = match m{
Message::Task(f) => Coroutine::spawn(f)
};
}
我收到以下错误:
src/main.rs:168:29: 168:45 error: the trait bound `for<'r> Box<for<'r> std::ops::FnOnce(&'r mut coroutine::asymmetric::Coroutine) + Send>: std::ops::FnOnce<(&'r mut coroutine::asymmetric::Coroutine,)>` is not satisfied [E0277]
src/main.rs:168 Message::Task(f) => Coroutine::spawn(f)
^~~~~~~~~~~~~~~~
src/main.rs:168:29: 168:45 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:168:29: 168:45 help: the following implementations were found:
src/main.rs:168:29: 168:45 help: <Box<std::boxed::FnBox<A, Output=R> + 'a> as std::ops::FnOnce<A>>
src/main.rs:168:29: 168:45 help: <Box<std::boxed::FnBox<A, Output=R> + Send + 'a> as std::ops::FnOnce<A>>
src/main.rs:168:29: 168:45 note: required by `coroutine::asymmetric::Coroutine::spawn`
我不知道 Rust 在这里想告诉我什么.我认为问题在于 spawn
需要一个非装箱函数,但如果我尝试取消引用装箱函数,我会得到同样的错误.
I have no idea what Rust is trying to tell me here. I assume that the problem is that spawn
expects a non boxed function, but I get the same error if I try to deref the boxed function.
请注意,在提出此问题时,coroutine-rs 未构建,我修复了 这个叉.
Note that at the time this question was asked, coroutine-rs doesn't build, and I fixed the errors in this fork.
推荐答案
让我们仔细阅读错误信息:
Let's read the error message carefully:
src/main.rs:168:29: 168:45 error: the trait bound
`for<'r>
Box<
for<'r> std::ops::FnOnce(
&'r mut coroutine::asymmetric::Coroutine
) + Send
>:
std::ops::FnOnce<
(
&'r mut coroutine::asymmetric::Coroutine,
)>` is not satisfied [E0277]
基本上,您试图将 Box
传递给需要实现 FnOnce
的类型的函数.
Basically, you are trying to pass a Box<FnOnce>
to a function that expects a type that implements FnOnce
.
然而,你不能调用Box
中的函数,因为为了调用它,你需要通过值传递self
,这意味着您需要取消对 Box
的引用,但这会产生一个未定义大小的类型,该类型不能按值传递(从 Rust 1.9 开始).
However, you cannot call a function that is in a Box<FnOnce>
, because in order to call it, you need to pass self
by value, which means that you need to dereference the Box
, but that yields an unsized type, which cannot be passed by value (as of Rust 1.9).
目前的解决方法是使用不稳定的FnBox
trait 而不是 FnOnce
.FnBox
自动为所有实现 FnOnce
的类型实现.以下是我们如何使用它:
The current workaround is to use the unstable FnBox
trait instead of FnOnce
. FnBox
is automatically implemented for all types that implement FnOnce
. Here's how we can use it:
#![feature(fnbox)]
use std::boxed::FnBox;
enum Message {
Task(Box<FnBox(&mut Coroutine) + Send + 'static>),
}
fn main() {
let m = Message::Task(Box::new(|me: &mut Coroutine| {
}));
let c = match m {
Message::Task(f) => Coroutine::spawn(|me| f.call_box((me,)))
};
}
注意对Command::spawn
的调用会收到一个调用FnBox
的闭包,因为我们不能直接传递FnBox
由于上述原因,Command::spawn
.另外,我必须在第一个闭包上显式注释参数类型,否则编译器会抱怨(预期的具体生命周期,找到绑定的生命周期参数
,我认为这是编译器中的一个错误).
Note that the call to Command::spawn
receives a closure that calls the FnBox
, because we can't pass the FnBox
directly to Command::spawn
for the reasons mentioned above. Also, I had to explicitly annotate the argument type on the first closure, otherwise the compiler complained (expected concrete lifetime, found bound lifetime parameter
, which I think is a bug in the compiler).
这篇关于特征界限不满足的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!