1. 程式人生 > Android開發 >WWDC 20 前你應該知道的 Swift 新特性(2):KeyPath 用作函式

WWDC 20 前你應該知道的 Swift 新特性(2):KeyPath 用作函式

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 的新特性。