WWDC 20 前你應該知道的 Swift 新特性(2):KeyPath 用作函式
阿新 • • 發佈:2020-06-24
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 的新特性。