Swift 5.8中仅实现同步load的类为何符合AsyncOverloaded协议?
为什么这段代码能正常编译运行?
这是因为Swift 5.5引入异步编程后,新增了同步函数自动适配异步协议要求的规则,具体原因如下:
你的协议定义了两个
load方法:一个同步无抛出的func load(),一个异步可抛出的func load() async throws。MyClass已经实现了第一个同步方法,而第二个异步方法的要求,Swift编译器会自动帮你完成适配。Swift的规则里,同步非抛出函数可以被自动提升为异步可抛出函数:
- 同步函数本身可以在异步上下文中执行,不需要额外挂起逻辑,天然满足
async的要求; throws修饰的函数允许实际不抛出任何错误,因此非抛出的同步函数也符合async throws的签名约束。
- 同步函数本身可以在异步上下文中执行,不需要额外挂起逻辑,天然满足
编译器会自动为
MyClass生成一个隐式的load() async throws实现,这个实现内部就是调用你写的同步load()方法,完全满足协议的要求。
你可以做个验证:如果把实例赋值给协议类型,调用异步方法也能正常运行:
let obj: AsyncOverloaded = MyClass() Task { try await obj.load() // 同样会打印"load called" }
简单来说,不是MyClass没遵守协议,而是Swift编译器帮你补全了异步方法的适配实现,所以代码能顺利编译运行。
内容的提问来源于stack exchange,提问作者Darko
相关产品推荐
相关产品推荐

