【问题标题】:swift constant inferred to have type () which may be unexpectedswift 常量推断为具有类型 (),这可能是出乎意料的
【发布时间】:2021-06-25 22:27:53
【问题描述】:

我有以下代码:

public func test_mutex() async
{
   let mutex = Mutex()
   async let a = mutex.exclusive("a") { await Tasks.after(ms: 300) {print("a")}}
   async let b = mutex.exclusive("b") { await Tasks.after(ms: 200) {print("b")}}
   async let c = mutex.exclusive("c") { await Tasks.after(ms: 100) {print("c")}}
   _ = await [a, b, c]
}

我得到了三个这样的错误:

Constant 'a' inferred to have type '()', which may be unexpected

然而 - 重点是我正在测试一个什么都不返回的函数 - 我有另一个测试一个返回一些东西的函数 - 即 () 一点也不意外 - 我不能只做这个返回一些东西。

如何摆脱警告? - 或者我如何以其他方式导致三个异步事件并行发生,然后等待它们。

【问题讨论】:

    标签: swift concurrency


    【解决方案1】:

    否则我如何导致三个异步事件并行发生然后等待它们

    您使用任务组,如结构化并发视频中所述。

    https://developer.apple.com/documentation/swift/3814991-withtaskgroup?changes=__1

    对组的async 方法的每次调用都是您调用异步方法以并行运行的机会。当所有调用完成后,任务上的await 完成,我们继续。

    或者,我想您可以按照 FixIt 的建议将 a、b 和 c 的类型声明为 ()。但这似乎是一种相当便宜的方法。最好正确地执行此操作。

    例如,我编造了一个行为,就像我想象的 Mutex 可能行为一样:

    class Waiter {
        func go(after:TimeInterval,  f: @escaping ()->()) async {
            await withUnsafeContinuation { (c:UnsafeContinuation<Void,Never>) in
                DispatchQueue.global().asyncAfter(deadline:.now()+after) {
                    f()
                    c.resume()
                }
            }
        }
    }
    

    然后编译并运行良好:

        let w = Waiter()
        async let x:() = w.go(after: 1) { print(1) }
        async let y:() = w.go(after: 1) { print(2) }
        async let z:() = w.go(after: 1) { print(3) }
        let _ = [await x, await y, await z]
    

    不过,我还是觉得任务组更好。

        let w = Waiter()
        print("start")
        await withTaskGroup(of:Void.self) { group in
            for i in [1,2,3] {
                group.async {
                    await w.go(after:1) { print(i) }
                }
            }
        }
        print("done")
    

    【讨论】:

    • 对不起 - 我可能很愚蠢 - 但我看不出在这种情况下如何使用任务组?至于宣布它们全部无效-尝试过-但它并没有使警告消失:(
    • 哦,好吧,给我一些时间,我给你写代码。我正在下载下一个测试版,所以我需要一段时间才能完成。 — 但是,实际上,我不确定互斥锁是什么,所以这可能更棘手。我的回答仅基于您问的一句话:要请求并行执行,请使用任务组。
    • 你能提供互斥代码吗?否则我想我可以编造一些东西。
    • 您尝试过 Fix-It 吗?
    • 没有修复它 - 但你给了我真正的解决方案 - 这只是 async let a: () = 不管我试过什么 async let a: Void = 不管什么谢谢。这是在测试中 - 所以我认为这比与任务组关联的所有代码要干净得多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    相关资源
    最近更新 更多