gpt4 book ai didi

rust - 不满足特征界限

转载 作者:行者123 更新时间:2023-11-29 07:50:55 24 4
gpt4 key购买 nike

Coroutine-rs

这是我要调用的函数:

#[inline]
pub fn spawn<F>(f: F) -> Handle
where F: FnOnce(&mut Coroutine) + Send + 'static
{
Self::spawn_opts_impl(Box::new(f), Options::default())
}

然后我创建了一个枚举,因为我实际上想将它从一个线程发送到另一个线程,这也是我将函数装箱的原因。我也匹配了特征约束。

enum Message {
Task(Box<FnOnce(&mut Coroutine) + Send + 'static>),
}

但是如果我尝试从 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 需要一个非装箱函数,但如果我尝试取消引用装箱函数,我会得到同样的错误。

请注意,在提出这个问题时,coroutine-rs 没有构建,我修复了 this fork 中的错误.

最佳答案

让我们仔细阅读错误信息:

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>到一个需要实现 FnOnce 的类型的函数.

但是,您不能调用 Box<FnOnce> 中的函数, 因为为了调用它,你需要传递 self按值,这意味着您需要取消引用 Box ,但这会产生一个未确定大小的类型,它不能按值传递(从 Rust 1.9 开始)。

当前的解决方法是使用不稳定的 FnBox 特征而不是 FnOnce . FnBox为实现 FnOnce 的所有类型自动实现.下面是我们如何使用它:

#![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由于上述原因。此外,我必须在第一个闭包中显式注释参数类型,否则编译器会报错( expected concrete lifetime, found bound lifetime parameter ,我认为这是编译器中的错误)。

关于rust - 不满足特征界限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37779313/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com