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 的新特性。
扫码下方二维码,关注“面试官小健”