![](/img/trans.png)
[英]Declaring Associated Type of Trait Object in Async Function Parameter
[英]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.