- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
以下代码是我尝试编写的代码的简化版本。
来自 Go,我发现处理相互调用的递归函数有点困难。
首先尝试(REPL on Playground here):
#[derive(Debug)]
struct Team {
id: String
}
impl Team {
pub async fn query(with_coach: bool) -> Result<Option<Team>, ()> {
if with_coach {
let coach = Coach::query(false).await?;
dbg!(coach);
}
Ok(None)
}
}
#[derive(Debug)]
struct Coach {
id: String
}
impl Coach {
pub async fn query(with_team: bool) -> Result<Option<Coach>, ()> {
if with_team {
let team = Team::query(false).await?;
dbg!(team);
}
Ok(None)
}
}
#[tokio::main]
async fn main() {
let team = Team::query(true).await;
dbg!(team);
}
错误是:
error[E0733]: recursion in an `async fn` requires boxing
--> src/main.rs:7:45
|
7 | pub async fn query(with_coach: bool) -> Result<Option<Team>, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^ recursive `async fn`
|
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
= note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
error[E0733]: recursion in an `async fn` requires boxing
--> src/main.rs:24:44
|
24 | pub async fn query(with_team: bool) -> Result<Option<Coach>, ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ recursive `async fn`
|
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
= note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
所以我尝试了第二个版本(REPL on Playground here):
use std::{future::Future, pin::Pin};
#[derive(Debug)]
struct Team {
id: String,
}
impl Team {
pub async fn query<'a>(
id: &'a str,
with_coach: bool,
) -> Pin<Box<dyn Future<Output = Result<Option<Team>, ()>> + Send + 'a>> {
Box::pin(async move {
if with_coach {
let coach = Coach::query("", false).await.await?;
dbg!(coach);
}
Ok(None)
})
}
}
#[derive(Debug)]
struct Coach {
id: String,
}
impl Coach {
pub async fn query<'a>(
id: &'a str,
with_team: bool,
) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
Box::pin(async move {
if with_team {
let team = Team::query("", false).await.await?;
dbg!(team);
}
Ok(None)
})
}
}
#[tokio::main]
async fn main() {
let team = Team::query("", true).await.await;
dbg!(team);
}
但是你可以想象有一个(非常奇怪的)错误:
error[E0391]: cycle detected when computing type of `<impl at src/main.rs:8:1: 8:10>::query::{opaque#0}`
--> src/main.rs:12:10
|
12 | ) -> Pin<Box<dyn Future<Output = Result<Option<Team>, ()>> + Send + 'a>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires borrow-checking `<impl at src/main.rs:8:1: 8:10>::query`...
--> src/main.rs:9:5
|
9 | / pub async fn query<'a>(
10 | | id: &'a str,
11 | | with_coach: bool,
12 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Team>, ()>> + Send + 'a>> {
| |____________________________________________________________________________^
note: ...which requires processing `<impl at src/main.rs:8:1: 8:10>::query`...
--> src/main.rs:9:5
|
9 | / pub async fn query<'a>(
10 | | id: &'a str,
11 | | with_coach: bool,
12 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Team>, ()>> + Send + 'a>> {
| |____________________________________________________________________________^
note: ...which requires processing MIR for `<impl at src/main.rs:8:1: 8:10>::query`...
--> src/main.rs:9:5
|
9 | / pub async fn query<'a>(
10 | | id: &'a str,
11 | | with_coach: bool,
12 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Team>, ()>> + Send + 'a>> {
| |____________________________________________________________________________^
note: ...which requires unsafety-checking `<impl at src/main.rs:8:1: 8:10>::query`...
--> src/main.rs:9:5
|
9 | / pub async fn query<'a>(
10 | | id: &'a str,
11 | | with_coach: bool,
12 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Team>, ()>> + Send + 'a>> {
| |____________________________________________________________________________^
note: ...which requires building MIR for `<impl at src/main.rs:8:1: 8:10>::query`...
--> src/main.rs:9:5
|
9 | / pub async fn query<'a>(
10 | | id: &'a str,
11 | | with_coach: bool,
12 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Team>, ()>> + Send + 'a>> {
| |____________________________________________________________________________^
note: ...which requires building THIR for `<impl at src/main.rs:8:1: 8:10>::query`...
--> src/main.rs:9:5
|
9 | / pub async fn query<'a>(
10 | | id: &'a str,
11 | | with_coach: bool,
12 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Team>, ()>> + Send + 'a>> {
| |____________________________________________________________________________^
note: ...which requires type-checking `<impl at src/main.rs:8:1: 8:10>::query`...
--> src/main.rs:13:9
|
13 | / Box::pin(async move {
14 | | if with_coach {
15 | | let coach = Coach::query("", false).await.await?;
16 | |
... |
20 | | Ok(None)
21 | | })
| |__________^
= note: ...which requires evaluating trait selection obligation `for<'r, 's, 't0> {core::future::ResumeTy, bool, &'r str, impl for<'s> core::future::future::Future<Output = core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = core::result::Result<core::option::Option<Coach>, ()>> + core::marker::Send + 's)>>>, (), core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = core::result::Result<core::option::Option<Coach>, ()>> + core::marker::Send + 't0)>>}: core::marker::Send`...
note: ...which requires computing type of `<impl at src/main.rs:30:1: 30:11>::query::{opaque#0}`...
--> src/main.rs:34:10
|
34 | ) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires borrow-checking `<impl at src/main.rs:30:1: 30:11>::query`...
--> src/main.rs:31:5
|
31 | / pub async fn query<'a>(
32 | | id: &'a str,
33 | | with_team: bool,
34 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
| |_____________________________________________________________________________^
note: ...which requires processing `<impl at src/main.rs:30:1: 30:11>::query`...
--> src/main.rs:31:5
|
31 | / pub async fn query<'a>(
32 | | id: &'a str,
33 | | with_team: bool,
34 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
| |_____________________________________________________________________________^
note: ...which requires processing MIR for `<impl at src/main.rs:30:1: 30:11>::query`...
--> src/main.rs:31:5
|
31 | / pub async fn query<'a>(
32 | | id: &'a str,
33 | | with_team: bool,
34 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
| |_____________________________________________________________________________^
note: ...which requires unsafety-checking `<impl at src/main.rs:30:1: 30:11>::query`...
--> src/main.rs:31:5
|
31 | / pub async fn query<'a>(
32 | | id: &'a str,
33 | | with_team: bool,
34 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
| |_____________________________________________________________________________^
note: ...which requires building MIR for `<impl at src/main.rs:30:1: 30:11>::query`...
--> src/main.rs:31:5
|
31 | / pub async fn query<'a>(
32 | | id: &'a str,
33 | | with_team: bool,
34 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
| |_____________________________________________________________________________^
note: ...which requires building THIR for `<impl at src/main.rs:30:1: 30:11>::query`...
--> src/main.rs:31:5
|
31 | / pub async fn query<'a>(
32 | | id: &'a str,
33 | | with_team: bool,
34 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
| |_____________________________________________________________________________^
note: ...which requires type-checking `<impl at src/main.rs:30:1: 30:11>::query`...
--> src/main.rs:35:9
|
35 | / Box::pin(async move {
36 | | if with_team {
37 | | let team = Team::query("", false).await.await?;
38 | |
... |
42 | | Ok(None)
43 | | })
| |__________^
= note: ...which requires evaluating trait selection obligation `for<'r, 's, 't0> {core::future::ResumeTy, bool, &'r str, impl for<'s> core::future::future::Future<Output = core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = core::result::Result<core::option::Option<Team>, ()>> + core::marker::Send + 's)>>>, (), core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = core::result::Result<core::option::Option<Team>, ()>> + core::marker::Send + 't0)>>}: core::marker::Send`...
= note: ...which again requires computing type of `<impl at src/main.rs:8:1: 8:10>::query::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module
--> src/main.rs:1:1
|
1 | / use std::{future::Future, pin::Pin};
2 | |
3 | | #[derive(Debug)]
4 | | struct Team {
... |
51 | | dbg!(team);
52 | | }
| |_^
error[E0391]: cycle detected when computing type of `<impl at src/main.rs:8:1: 8:10>::query::{opaque#0}`
--> src/main.rs:12:10
|
12 | ) -> Pin<Box<dyn Future<Output = Result<Option<Team>, ()>> + Send + 'a>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires borrow-checking `<impl at src/main.rs:8:1: 8:10>::query`...
--> src/main.rs:9:5
|
9 | / pub async fn query<'a>(
10 | | id: &'a str,
11 | | with_coach: bool,
12 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Team>, ()>> + Send + 'a>> {
| |____________________________________________________________________________^
note: ...which requires processing `<impl at src/main.rs:8:1: 8:10>::query`...
--> src/main.rs:9:5
|
9 | / pub async fn query<'a>(
10 | | id: &'a str,
11 | | with_coach: bool,
12 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Team>, ()>> + Send + 'a>> {
| |____________________________________________________________________________^
note: ...which requires processing MIR for `<impl at src/main.rs:8:1: 8:10>::query`...
--> src/main.rs:9:5
|
9 | / pub async fn query<'a>(
10 | | id: &'a str,
11 | | with_coach: bool,
12 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Team>, ()>> + Send + 'a>> {
| |____________________________________________________________________________^
note: ...which requires unsafety-checking `<impl at src/main.rs:8:1: 8:10>::query`...
--> src/main.rs:9:5
|
9 | / pub async fn query<'a>(
10 | | id: &'a str,
11 | | with_coach: bool,
12 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Team>, ()>> + Send + 'a>> {
| |____________________________________________________________________________^
note: ...which requires building MIR for `<impl at src/main.rs:8:1: 8:10>::query`...
--> src/main.rs:9:5
|
9 | / pub async fn query<'a>(
10 | | id: &'a str,
11 | | with_coach: bool,
12 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Team>, ()>> + Send + 'a>> {
| |____________________________________________________________________________^
note: ...which requires building THIR for `<impl at src/main.rs:8:1: 8:10>::query`...
--> src/main.rs:9:5
|
9 | / pub async fn query<'a>(
10 | | id: &'a str,
11 | | with_coach: bool,
12 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Team>, ()>> + Send + 'a>> {
| |____________________________________________________________________________^
note: ...which requires type-checking `<impl at src/main.rs:8:1: 8:10>::query`...
--> src/main.rs:13:9
|
13 | / Box::pin(async move {
14 | | if with_coach {
15 | | let coach = Coach::query("", false).await.await?;
16 | |
... |
20 | | Ok(None)
21 | | })
| |__________^
= note: ...which requires evaluating trait selection obligation `for<'r, 's, 't0> {core::future::ResumeTy, bool, &'r str, impl for<'s> core::future::future::Future<Output = core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = core::result::Result<core::option::Option<Coach>, ()>> + core::marker::Send + 's)>>>, (), core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = core::result::Result<core::option::Option<Coach>, ()>> + core::marker::Send + 't0)>>}: core::marker::Send`...
note: ...which requires computing type of `<impl at src/main.rs:30:1: 30:11>::query::{opaque#0}`...
--> src/main.rs:34:10
|
34 | ) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires borrow-checking `<impl at src/main.rs:30:1: 30:11>::query`...
--> src/main.rs:31:5
|
31 | / pub async fn query<'a>(
32 | | id: &'a str,
33 | | with_team: bool,
34 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
| |_____________________________________________________________________________^
note: ...which requires processing `<impl at src/main.rs:30:1: 30:11>::query`...
--> src/main.rs:31:5
|
31 | / pub async fn query<'a>(
32 | | id: &'a str,
33 | | with_team: bool,
34 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
| |_____________________________________________________________________________^
note: ...which requires processing MIR for `<impl at src/main.rs:30:1: 30:11>::query`...
--> src/main.rs:31:5
|
31 | / pub async fn query<'a>(
32 | | id: &'a str,
33 | | with_team: bool,
34 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
| |_____________________________________________________________________________^
note: ...which requires unsafety-checking `<impl at src/main.rs:30:1: 30:11>::query`...
--> src/main.rs:31:5
|
31 | / pub async fn query<'a>(
32 | | id: &'a str,
33 | | with_team: bool,
34 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
| |_____________________________________________________________________________^
note: ...which requires building MIR for `<impl at src/main.rs:30:1: 30:11>::query`...
--> src/main.rs:31:5
|
31 | / pub async fn query<'a>(
32 | | id: &'a str,
33 | | with_team: bool,
34 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
| |_____________________________________________________________________________^
note: ...which requires building THIR for `<impl at src/main.rs:30:1: 30:11>::query`...
--> src/main.rs:31:5
|
31 | / pub async fn query<'a>(
32 | | id: &'a str,
33 | | with_team: bool,
34 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
| |_____________________________________________________________________________^
note: ...which requires type-checking `<impl at src/main.rs:30:1: 30:11>::query`...
--> src/main.rs:31:5
|
31 | / pub async fn query<'a>(
32 | | id: &'a str,
33 | | with_team: bool,
34 | | ) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
| |_____________________________________________________________________________^
= note: ...which again requires computing type of `<impl at src/main.rs:8:1: 8:10>::query::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module
--> src/main.rs:1:1
|
1 | / use std::{future::Future, pin::Pin};
2 | |
3 | | #[derive(Debug)]
4 | | struct Team {
... |
51 | | dbg!(team);
52 | | }
| |_^
这是什么意思?
如何修复此代码?
最佳答案
你们很亲密。当您返回盒装 future 时,您只是不需要异步。更多详情 here和 here
Async fn 创建一个状态机类型,其中包含每个正在等待的子 Future。对于递归异步函数,生成的状态机类型必须包含自身,以便您获得无限大小的类型。所以你必须把它装箱。
然而,编译器限制目前不允许仅装箱。您必须将递归函数转换为非异步函数,该函数返回一个装箱的异步 block 。
编译并运行:
use std::{future::Future, pin::Pin};
#[derive(Debug)]
struct Team {
id: String,
}
impl Team {
pub fn query<'a>(
id: &'a str,
with_coach: bool,
) -> Pin<Box<dyn Future<Output = Result<Option<Team>, ()>> + Send + 'a>> {
Box::pin(async move {
if with_coach {
let coach = Coach::query("", false).await?;
dbg!(coach);
}
Ok(None)
})
}
}
#[derive(Debug)]
struct Coach {
id: String,
}
impl Coach {
pub fn query<'a>(
id: &'a str,
with_team: bool,
) -> Pin<Box<dyn Future<Output = Result<Option<Coach>, ()>> + Send + 'a>> {
Box::pin(async move {
if with_team {
let team = Team::query("", false).await?;
dbg!(team);
}
Ok(None)
})
}
}
#[tokio::main]
async fn main() {
let team = Team::query("", true).await;
dbg!(team);
}
关于asynchronous - 相互调用的递归异步函数 : cycle detected,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74737595/
来自 Akka 文档,Pipelining and Parallelism Akka Streams processing stages (be it simple operators on Flow
我正在开发一个提取元数据的 chrome 扩展程序。解析元数据的代码包含在内容脚本中。 background.js 和 content.js 通过 sendMessage 请求和响应进行通信。我遇到了
我正在使用 Python 3.7.4 和这段代码(MWE): import asyncio async def foo(x): await asyncio.sleep(1) retur
嘿,我对 Dart Futures 很陌生,我有以下情况。 每当用户在 UI 中键入一个字母时,addressChanged()我的 ui_component 中的方法被调用。该方法调用方法getPr
我在尝试将异步函数转换为同步函数时遇到问题。 这是类中的一个方法: doPost: function(call, data) { var uri = 'http://localhost/api
在很多关于 C# 的 async/await 的讨论中,我看到人们提到了“自然异步”或“纯异步”的术语。这些术语到底是什么意思? “自然异步”操作的一些示例是什么?为什么这样调用它? “非自然异步”操
现在我正在使用 Gevent,我想问两个问题: 有没有办法执行特定的任务,这将 从不异步执行 (而不是在每个任务中使用锁) 有没有办法到优先在 Gevent 中生成任务?就像一组将以低优先级生成的任务
在 document , 如果方法也用@gen.coroutine 修饰,则不需要@web.asynchronous。像这样 @web.asynchronous @gen.coroutine def
已在 Google Analytics(分析)帮助论坛中发布此内容,但无人能提供帮助。希望我在这里有更多的运气......: 我对我的网页使用 Google Anlaytics 异步跟踪。像个魔法一样
我正在尝试从 Controller 异步发送电子邮件并收到以下错误: 我不想等待电子邮件发送完成操作。 An asynchronous module or handler completed whil
在使用 SendMailAsync 时出现以下错误: An asynchronous module or handler completed while an asynchronous operati
我有一个非常简单的 ASP.NET MVC 4 Controller : public class HomeController : Controller { private const st
我正在编写一个使用 ASP.NET Web API 代理一些 HTTP 请求的应用程序,我正在努力识别间歇性错误的来源。这似乎是一个竞争条件...但我不完全确定。 在详细介绍之前,先介绍应用程序的一般
Cancel CancellationTokenSource 的成员对象“传达取消请求”,我认为这意味着它是触发并忘记并且不会等到取消完成(例如,所有异常处理程序都已运行)。这很好,但我需要等到一个未
在 D 中异步调用其他进程的首选方法是什么?我的用例正在调用 svn status检查退出状态,并解析其标准输出和错误。 最佳答案 我想 std.stdio.popen是你想要的: void pope
我一直听说使用异步编程模式会使我的代码运行得更快。为什么这是真的?无论是现在运行还是稍后运行,都不是必须以任何一种方式运行完全相同的代码吗? 最佳答案 它不是更快,它只是不浪费时间。 同步代码在等待
我有点困惑为什么同步调用与异步调用不同,因为从来没有“立即”响应,它仍然需要几纳秒或几毫秒? 最佳答案 同步调用在完成其工作(或达到超时)后返回其调用者。异步调用在启动其他事件后立即返回。 这意味着,
我正在尝试使用 MSDN 上描述的 OVERLAPPED 结构异步调用 DeviceIO 函数。 我正在使用 FSCTL_ENUM_USN_DATA 控制代码来枚举 NTFS 驱动器的 MFT,但我无
我一直在尝试创建一个服务器进程,以异步方式从客户端进程接收输入文件路径和输出路径。服务器进行了一些与数据库有关的转换,但是为了简单起见,我们假设它只是将所有内容都转换为大写。这是服务器的一个玩具示例:
我正在编写一个异步方法,它应该异步查询一个端口,直到找到一个,或者在 5 分钟后超时; member this.GetPort(): Async = this._GetPort(DateTim
我是一名优秀的程序员,十分优秀!