簡體   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