Swift 5.2 中新增的另一个的语言小特性是:KeyPath 用作函数。对于 KeyPath 还不熟悉的同学可以先看一下这篇文章:SwiftUI 和 Swift 5.1 新特性(3) Key Path Member Lookup。
在介绍 KeyPath 的时候我们介绍过,一个 KeyPath<Root, Value> 的实例定义了从 Root 类型中获取 Value 类型的方式,它同时能被看作是 (Root) -> Value 类型的一个实例。
struct User {
let name: String
}
users.map{$0.name}
users.map(\.name)
复制代码上面的例子中 map 需要一个 (User) -> String 的函数实例,在 Swift 5.2 中,我们可以直接传入 \User.name KeyPath,由于类型推断,可以进一步简化成\.name。它等价于users.map { $0[keyPath: \.name] }
然而,非字面值的 KeyPath 是不支持的。
let keyPath = \User.name
users.map(keyPath)
复制代码上面的代码会提示编译错误:Cannot convert value of type 'KeyPath<User, String>' to expected argument type '(User) throws -> T',
直接传不行,因为类型不匹配。为了解决这个问题,可以显式地转换成函数形式。
let f: (User) -> String = \.name
let f2 = \.name as (User) -> String
复制代码编译器会生成类似的函数:
let f: (User) -> String = { kp in { root in root[keyPath: kp] } }(\User.name)
复制代码结语
Swift 5.2 中的语言特性介绍完了,让我们一起期待 WWDC 20 以及 Swift 5.3 的新特性。
扫码下方二维码,关注“面试官小健”