pub async fn send_and_expect(&mut self, request: rtsp_types::Request<Body>, retrying: bool) -> std::result::Result<rtsp_types::Response<Body>, ClientActionError> {
Run Code Online (Sandbox Code Playgroud)
我得到:
pub async fn send_and_expect(&mut self, request: rtsp_types::Request<Body>, retrying: bool) -> std::result::Result<rtsp_types::Response<Body>, ClientActionError> {
Run Code Online (Sandbox Code Playgroud)
我找到了https://rust-lang.github.io/async-book/07_workarounds/04_recursion.html但它适用于不使用async
.
这里应该走什么路?
我发现为什么递归异步函数需要“Rust 中的静态参数?” 我将我的功能更改为
pub fn send_and_expect(&mut self, request: rtsp_types::Request<Body>, retrying: bool)
-> Pin<Box<dyn Future <Output = std::result::Result<rtsp_types::Response<Body>, ClientActionError>>>> {
Run Code Online (Sandbox Code Playgroud)
但现在我不能await
在我的函数中使用。另外,我该如何退货?
例如:
return Box::pin(Err(ClientActionError::CSeqMissing))
Run Code Online (Sandbox Code Playgroud)
行不通
更新:
根据下面的答案,我在递归调用中得到了这个:
194 | }.boxed()
| ^^^^^ future created by async block is not `Send`
|
= help: the trait `std::marker::Send` is not implemented for `dyn futures::Future<Output = std::result::Result<rtsp_types::Response<Body>, ClientActionError>>`
note: future is not `Send` as it awaits another future which is not `Send`
--> src/client.rs:170:36
|
170 | ... return self.send_and_expect(request.clone(), true).await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `Pin<Box<dyn futures::Future<Output = std::result::Result<rtsp_types::Response<Body>, ClientActionError>>>>`, which is not `Send`
Run Code Online (Sandbox Code Playgroud)
更新2:
error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> src/client.rs:156:20
|
154 | pub fn send_and_expect(&mut self, request: rtsp_types::Request<Body>, retrying: bool)
| --------- this data with an anonymous lifetime `'_`...
155 | -> Pin<Box<dyn Future<Output = std::result::Result<rtsp_types::Response<Body>, ClientActionError>>+ Send>> {
156 | async move {
| ____________________^
157 | | let expected_cseq_header_value = rtsp_types::HeaderName::from_static_str("cseq").unwrap();
158 | | let expected_cseq = request.header(&expected_cseq_header_value);
159 | | let expected_cseq = match expected_cseq {
... |
193 | | Err(ClientActionError::Teardown)
194 | | }.boxed()
| |_________^ ...is captured here, requiring it to live as long as `'static`
|
help: to declare that the trait object captures data from argument `self`, you can add an explicit `'_` lifetime bound
|
155 | -> Pin<Box<dyn Future<Output = std::result::Result<rtsp_types::Response<Body>, ClientActionError>>+ Send + '_>> {
| ^^^^
Run Code Online (Sandbox Code Playgroud)
我找到了 [...] 但它是针对不使用
async
.
是的,它确实。您应该仔细查看代码。原来的函数肯定是async
:
async fn recursive() {
recursive().await;
recursive().await;
}
Run Code Online (Sandbox Code Playgroud)
...但现在我不能
await
在我的函数中使用。
async {}
如果您按照修复建议进行阻止,则可以:
use futures::future::{BoxFuture, FutureExt};
fn recursive() -> BoxFuture<'static, ()> {
async move {
recursive().await; // you can use await here
recursive().await;
}.boxed()
}
Run Code Online (Sandbox Code Playgroud)
这个想法只是需要装箱异步返回类型而不是impl Future
. 因此,解决方法是创建一个async {}
块,在其中正常运行函数,然后将其装箱以返回它。async
这避免了嵌套/await
函数被单态化在一起引起的问题。
所以你应该能够:
pub fn send_and_expect(&mut self, request: rtsp_types::Request<Body>, retrying: bool)
-> Pin<Box<dyn Future<Output = std::result::Result<rtsp_types::Response<Body>, ClientActionError>> + Send>> {
// ^^^^^^
async move {
// put your original code here
}.boxed()
}
Run Code Online (Sandbox Code Playgroud)
另外,我该如何退货?
您可以通过块中的最后一个表达式正常返回内容async
,也可以使用return
. 您应该与正确功能相同async
,不用担心Box::pin(...)
.
如果您需要Future
满足任何其他特征边界(Send
、Sync
、Unpin
等),那么您可以将其与dyn Future<...>
返回类型需要dyn Future<Output = ...> + Send
使用.boxed()
.
async
如果无法创建块的内容Send
,您可以像这样手动完成(尽管大多数运行时都希望Future
s 如此Send
,所以您很难使用它):
fn recursive() -> Pin<Box<dyn Future<Output = ()>>> {
Box::pin(async move {
recursive().await;
recursive().await;
})
}
Run Code Online (Sandbox Code Playgroud)