pub async fn send_and_expect(&mut self, request: rtsp_types::Request<Body>, retrying: bool) -> std::result::Result<rtsp_types::Response<Body>, ClientActionError> {
字符串
我明白了:
recursion in an `async fn` requires boxing
recursive `async fn`
note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`rustc(E0733)
型
我找到了https://rust-lang.github.io/async-book/07_workarounds/04_recursion.html,但它是一个不使用async
的函数。
这里应该怎么走呢?
我找到了Why recursive async functions require 'static parameters in 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>>>> {
型
但是现在我不能在我的函数里面使用await
了。还有,我怎么返回东西呢?
举例来说:
return Box::pin(Err(ClientActionError::CSeqMissing))
型
行不通
更新:
根据下面的答案,我在递归调用中得到了这个:
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`
型
更新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 + '_>> {
| ^^^^
型
2条答案
按热度按时间mcvgt66p1#
我找到了[...],但它是一个不使用
async
的函数。是的。你应该仔细看看代码。原始函数肯定是
async
:字符串
.但是现在我不能在函数中使用
await
。如果你按照修复建议创建一个
async {}
块,你就可以:型
这个想法很简单,因为
async
/await
的返回类型需要被装箱,而不是impl Future
。所以修复方法是创建一个async {}
块,在其中正常运行函数,然后将其装箱以返回它。这避免了嵌套的async
/await
函数被单态化在一起所导致的问题。因此,您应该能够:
型
还有,我怎么退东西?
你可以通过
async
块中的最后一个表达式返回正常的东西,或者你可以使用return
。你应该和一个正确的async
函数一样,不要担心Box::pin(...)
。如果您需要
Future
来满足任何其他trait边界(Send
、Sync
、Unpin
等),那么您可以沿着dyn Future<...>
来指定它返回类型要求
dyn Future<Output = ...> + Send
使用.boxed()
。如果
async
块的内容不能被设置为Send
,你可以像这样手动设置(尽管大多数运行时都希望Future
s是Send
,所以你很难使用它):型
ars1skjm2#
另外,为了帮助其他人,有一个crate提供了一个宏来自动重写整个复杂的函数:https://docs.rs/async-recursion/latest/async_recursion。