[英]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.