如何在mojo中编写异步代码? (“协程不可复制”)

问题描述 投票:0回答:1

如何在mojo中实现异步代码(使用

async
等)?

Changelog中,我找到以下示例(略有调整):

async fn add_three(a: Int, b: Int, c: Int) -> Int:
    return a + b + c

async fn call_it():
    var task = add_three(1, 2, 3)
    print(await task)

这给了我以下编译器错误:

test_async.mojo:39:17: error: 'Coroutine[Int, {}]' is not copyable because it has no '__copyinit__'
    print(await task)
                ^~~~

我不明白这个错误,因为我认为

Coroutine
是可以寄存器通过的(如源代码中所示)。有效的是

async fn add_three(a: Int, b: Int, c: Int) -> Int:
    return a + b + c

async fn call_it():
    var task = await add_three(1, 2, 3)
    print(task)

但是,如果我总是将

await
放在右侧,我将永远无法异步执行代码,因为我总是在等待该行完成。我做错了什么/我的误解在哪里? (或者这只是一个错误?)

在变更日志中,它还表示任务可以在完成后“恢复”(请参阅此处)。 “恢复”是什么意思以及我该怎么做?

我正在开发当前的夜间构建版本:mojo 2024.7.2005 (96a1562c)。

注意:我也在mojo的问答页面发布了这个问题,但到目前为止还没有看到任何反应。如果我在那里收到答案,我会更新这篇文章。

async-await mojolang
1个回答
0
投票

问题在于协程(

async
函数的结果)不可复制;即它只能存在一次。这是有道理的,因为副本需要指向相同的异步任务,这意味着副本并不是“真正”相互独立。

解决方案是调用 move init,这可以通过此处的

^
运算符来完成。该运算符确保协程变量的值之后不再使用并转移所有权。

async fn call_it():
    var task = add_three(1, 2, 3)
    print(await task^)

这就像魅力一样。同样,我们也可以将最终结果移动到另一个“经典”变量(即不是协程):

async fn call_it():
    var task = add_three(1, 2, 3)
    var other = await task^
    print(other)
© www.soinside.com 2019 - 2024. All rights reserved.