trait MethodTrait {
async fn async_method(&self);
}
#[derive(Clone)]
struct MyStruct {}
impl MethodTrait for MyStruct {
async fn async_method(&self) {
todo!() // 占位
}
}
struct Demo<T>
where
T: MethodTrait + Clone + Sync + Send + 'static,
{
parser: T,
}
impl<T> Demo<T>
where
T: MethodTrait + Clone + Sync + Send + 'static,
{
fn new(parser: T) -> Self {
Demo { parser }
}
async fn execute(&self) {
let parser = self.parser.clone();
tokio::spawn(async move {
// parser.async_method().await; // 这里会报错
test_fn().await; // 这里正常执行
});
}
}
#[tokio::main]
async fn main() {
let my_struct = MyStruct {};
let demo = Demo::new(my_struct);
demo.execute().await;
}
async fn test_fn() {
println!("hello world")
}
错误信息: the trait Send
is not implemented for impl Future<Output = ()>
, which is required by : Send
这里没搞懂为什么不能直接写async方法,要写同步方法然后自己手动约束返回值的send。
1
共 7 条评论, 1 页
评论区
写评论感谢大佬耐心解答,我知道了
--
👇
TinusgragLin: > 我没搞懂这块为啥需要约束Send
哦,我知道了,你的疑惑是不是为啥 tokio::spawn 需要一个 Send 的 Future?
如果我理解没错的话,这是因为 tokio 的任务调度系统默认开了任务窃取,如果某个 worker 线程闲得发慌可以把其他 worker 线程任务队列中的 Future 给这个线程,所以需要 Future 的 ownership 可以在不同线程间转移,所以需要 Send 约束,字节有一个(为负载均衡任务设计的)monoio 异步运行时就没有这个要求了。
哦,我知道了,你的疑惑是不是为啥 tokio::spawn 需要一个 Send 的 Future?
如果我理解没错的话,这是因为 tokio 的任务调度系统默认开了任务窃取,如果某个 worker 线程闲得发慌可以把其他 worker 线程任务队列中的 Future 给这个线程,所以需要 Future 的 ownership 可以在不同线程间转移,所以需要 Send 约束,字节有一个(为负载均衡任务设计的)monoio 异步运行时就没有这个要求了。
学到了 https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=41b5bb02843224f46c7eb5fdedfe44e5
--
👇
TinusgragLin: 如果我记得没错的话,目前 trait 中的 async 方法返回的 Future 默认是没有 Send 约束的,不过现在 nightly 有了 return type notation 之后,就可以加一个这样的约束了:
把
改成
参考 https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-traits.html#async-fn-in-public-traits
大概是因为现在 trait 中的 async 方法实际上跟这样写
差不多,返回值是一个“opaque type”(实际类型“隐藏”的类型),对于类型系统来说,这就是“某一个”实现了的 Future trait 的类型,而不会考虑它的实际类型,所以类型检查的时候会很保守。
之前官方的博客有一篇相关的文章,你可以参考一下。
我没搞懂这块为啥需要约束Send
--
👇
TinusgragLin: 如果我记得没错的话,目前 trait 中的 async 方法返回的 Future 默认是没有 Send 约束的,不过现在 nightly 有了 return type notation 之后,就可以加一个这样的约束了:
如果我记得没错的话,目前 trait 中的 async 方法返回的 Future 默认是没有 Send 约束的,不过现在 nightly 有了 return type notation 之后,就可以加一个这样的约束了: