与 Swift @escaping 的小故事

在半年前的一次面试中...

面试官:网络请求的 block 怎么写的?

我:func request(completion: (() -> Void)?)

面试官:不需要加 @escaping 吗?

我:不需要

面试官:为什么?

我:这个闭包是可选的

面试官:这是一个逃逸闭包,逃逸闭包要加 @escaping,和闭包是不是可选有什么关系?

我:不知道...

内心OS:我也不知道为什么啊...可我这么写没报错啊...

先说结论,以下两个方法都不会报错,接下来就来说说为什么第二个方法不会报错。

func request(completion: @escaping () -> Void) { }
func request(completion: (() -> Void)?) { }

首先我们要知道可选类型的本质是什么?可选类型的本质是一个枚举,声明如下。

public enum Optional<Wrapped> : ExpressibleByNilLiteral {
    case none
    case some(Wrapped)
}

所以第二个方法实际上是这样子的。

func request(completion: Optional<() -> Void>) { }

因为可选闭包本质是一个枚举,completion 参数传递的是一个枚举,所以不需要加上 @escaping

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容