繁体   English   中英

使用,在异步上发送 object function 可以工作,但不能在 trait function 上工作

[英]Using !Send object on async function works, but does not work on trait function

假设我们有一个不是 Send 的类型。

 struct NotSend { field: std::rc::Rc<i32> }

然后,按照 async function 仍然可以将 NotSend 作为其参数并且编译良好:

 async fn func(not_send: NotSend) -> i32 { 0 }

但是当我在特征内部定义相同的 function 时,任何实现它的东西都不会编译。

 #[async_trait] trait A { async fn func(not_send: NotSend) -> i32; } struct S { } #[async_trait] impl A for S { async fn func(not_send: NotSend) -> i32 { 0 } }

这失败并显示以下消息:

 error: future cannot be sent between threads safely --> src/main.rs:23:46 | 23 | async fn func( not_send: NotSend) -> i32 { | ______________________________________________^ 24 | | 0 25 | | } | |_____^ future created by async block is not `Send` | = help: within `impl Future<Output = i32>`, the trait `Send` is not implemented for `Rc<i32>` note: captured value is not `Send` --> src/main.rs:23:20 | 23 | async fn func( not_send: NotSend) -> i32 { | ^^^^^^^^ has type `NotSend` which is not `Send` = note: required for the cast to the object type `dyn Future<Output = i32> + Send`

与天真的 function 和 function 有什么不同? 为什么一个有效,而另一个无效? 游乐场链接

这是因为async_trait扩展为Pin<Box<dyn Future>>之类的东西。 如果我们希望得到的未来是Send ,它需要是Pin<Box<dyn Future>> + Send 但这会强制它为Send ,即在非Send期货上会出错。 async_trait crate 没有办法知道未来是否是Send (因为 trait 的实现与其声明不同,我们需要在声明站点决定未来是否为Send ),所以它选择使用用户定义的注释。

默认情况下,生成的类型是Send因为大多数期货需要是Send 但是, 如文档中所述,您可以使用#[async_trait(?Send)]来选择退出:

 #[async_trait(?Send)] trait A { async fn func(not_send: NotSend) -> i32; } struct S { } #[async_trait(?Send)] impl A for S { async fn func(not_send: NotSend) -> i32 { 0 } }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM