【问题标题】:What is the type of `async let` declaration in Swift?Swift 中的 `async let` 声明的类型是什么?
【发布时间】:2021-06-13 15:49:34
【问题描述】:

Swift 5.5 引入了协程、分层任务管理和函数挂起。 新功能之一是语法

async let image = downloadImage(url)

图像的声明可以是await'ed。但问题是,它的类型是什么? Xcode 说它的类型是什么?我可以为函数参数声明什么类型来接受这个对象?

【问题讨论】:

  • 好问题。正如你在尝试时所看到的,Xcode 只会报告它被声明为async let image: UIImage。 Xcode 变量检查器只会说它是UIImage。没有通用的包装器类型,就像我们习惯于在组合类型中看到的那样。但它也不仅仅是一个简单的UIImage,因为你不能只使用它而不用await(或try await)修饰后续引用。
  • FWIW,如果您正在寻找术语,变量 imagetypeUIImage,但在幕后,编译器会为它创建一个task,即“async-let binding”任务。见Explore structured concurrency in Swift
  • @Rob 是的,谢谢你,我想了这么多!但是 - 这是一个问题......如何将实例化的async let 传递给函数!除了通过明显的“异步关闭”方法之外,还无法解决这个问题......
  • 当您将其作为参数提供给该函数时,您通常只会使用await(或try await)。

标签: swift asynchronous async-await static-typing


【解决方案1】:

问题是,它的类型是什么?

这个问题的解决方法与 any 变量声明的初始化方式相同:通过等号右侧的类型。

例如,如果您有一个返回字符串的方法(我们将其命名为getMyString),那么当您说

let s = getMyString()

...s 类型为 String,从被调用方法的返回类型推断。

嗯,async let 没有什么不同:

async let s = getMyString()

如果getMyString 返回一个字符串,s 将是一个字符串。

唯一的区别是,ex hypothesi,String 是 异步返回的。但这对这里的整体语法没有影响。这就是async/await 的全部;它让您可以在正常的 Swift 语法范围内异步调用代码(而不必用 GCD 闭包绕着月亮跳舞)。

【讨论】:

  • 好的,所以这在语法上意味着此时检查此成员会显示任务的整体未来结果,而不是基础类型,例如Task<UIImage>Future<UIImage> 等。感谢您的检查
【解决方案2】:

与许多其他编程语言不同,Swift 的并发模型根本不使用FuturePromise 或类似类型。 表达式要么需要awaited,要么不需要。

因此,可以在其他编程语言(例如 JavaScript)中使用 async/await 实现的东西在 Swift 中不起作用:

func test() async {
    let a = getNumber() // error: Expression is 'async' but is not marked with 'await'
    print(await a) // warning: No 'async' operations occur within 'await' expression
}

func getNumber() async -> Int {
    42
}

这是async let 语法的原因之一:它允许您调用异步函数,但将awaiting 推迟到以后。

【讨论】:

  • 是的,这正是我试图为自己解决的问题——为什么任务的底层形而上学类型没有像在 ECMAScript 中那样暴露给程序员......跨度>
  • @IsaaсWeisberg 我相信这都是关于效率/性能的。 Doug Gregor 在本期播客中详细介绍了设计:swiftbysundell.com/podcast/99
猜你喜欢
  • 2017-11-02
  • 2012-11-17
  • 2015-05-25
  • 1970-01-01
  • 1970-01-01
  • 2020-05-12
  • 2016-08-19
  • 2011-04-16
  • 1970-01-01
相关资源
最近更新 更多