Swift 5.5 async let - 错误:表达式为“async”但未标记为“await”

dre*_*ter 7 asynchronous let ios async-await swift

WWDC21 引入了带有async/await 的Swift 5.5。在探索 Swift 中的结构化并发在 Swift WWDC21 会话中遇到 async/await 之后,我正在尝试使用async let函数。

这是我的游乐场代码:

func doIt() async -> String {
    let t = TimeInterval.random(in: 0.25 ... 2.0)
    Thread.sleep(forTimeInterval: t)
    return String("\(Double.random(in: 0...1000))")
}

async {
    async let a = doIt()
    async let b = doIt()
    async let c = doIt()
    async let d = doIt()
    
    let results = await [a, b, c, d]
    for result in results {
        print("  \(result)")
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,对于每个“async let”行,我都会收到此错误:

error: AsyncLetSwift55WWDC21.playground:12:15: error: expression is 'async' but is not marked with 'await'
    async let a = doIt()
              ^
              await 
Run Code Online (Sandbox Code Playgroud)

Paul Hudson 的博客展示了这个例子: Hacking With Swift async 让例子

探索结构化货币视频在 8:10 左右有这个例子: 在此处输入图片说明

编辑:这似乎是 Playground 特定的问题。根据Apple Developer Forums 中关于同一问题的建议,运行相同的代码(好吧,我确实sleep(10)在 macOS 的异步块之后添加到源文件的末尾,因此应用程序不会在异步调用完成之前终止)作为macOS 命令行项目不会出错并产生正确的输出。

这是一个错误,还是我只是不明白什么?

mat*_*att 8

我的建议是:不要在操场上尝试这个。游乐场还没有为这些东西做好准备。您的代码在实际项目中编译并运行良好。这是一个例子:

class ViewController: UIViewController {
    
    func doIt() async -> String {
        let t = TimeInterval.random(in: 0.25 ... 2.0)
        Thread.sleep(forTimeInterval: t)
        return String("\(Double.random(in: 0...1000))")
    }
    func test() {
        async {
            async let a = doIt()
            async let b = doIt()
            async let c = doIt()
            async let d = doIt()
            
            let results = await [a, b, c, d]
            for result in results {
                print("  \(result)")
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        test()
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 据我所知,“Task.sleep”目前仅适用于非常小的值。不知道这是怎么回事。 (2认同)

dre*_*ter 4

构建为 macOS 命令行项目(Xcode:文件 -> 新建 -> 项目,然后从 macOS 选项卡中选择“命令行工具”),代码完美运行。 (这是Apple 开发者论坛的回复中的建议。)

sleep(10)我在末尾添加了一个,以便命令行工具在异步调用完成之前不会退出:

import Foundation

print("Hello, world!")

func doIt() async -> String {
    let t = TimeInterval.random(in: 0.25 ... 2.0)
    Thread.sleep(forTimeInterval: t)
    return String("\(Double.random(in: 0...1000))")
}

async {
    async let a = doIt()
    async let b = doIt()
    async let c = doIt()
    async let d = doIt()
    
    let results = await [a, b, c, d]
    for result in results {
        print("  \(result)")
    }
}
sleep(10)
Run Code Online (Sandbox Code Playgroud)

这会产生预期的控制台输出类型(注意:每次运行的实际值都会有所不同)*:

Hello, World!
  415.407747869283
  574.28639828183
  689.4706625185836
  385.56539085197113
Program ended with exit code: 0
Run Code Online (Sandbox Code Playgroud)