const user = { name: 'Joe', age: 18 };
const key = 'name';
const v = user[key];
而在 Swift 中, 实现类似功能的方法为 Key-Path 表达式.
struct User {
var name: String
var address: String
}
let u = User(name: "Joe", address: "NY")
var pathToProperty = \User.name
if (Int.random(in: 1...10) > 5) {
pathToProperty = \User.address
}
let value = u[keyPath: pathToProperty]
print("value", value);
不过从上述例子中我们也能看到, Swift 为了保证后续使用 path 时的类型安全, 在定义 pathToProperty 时已经推断类型为 WritableKeyPath<User, String>, 而不是 WritableKeyPath<User, String or Int>.
根据上下文省略类型的 Key-Path 表达式
Key-Path 表达式有两大部分组成:
类型
路径
其中, 前者在上下文充分时是可以省略的.
比如官方例子中:
class SomeClass: NSObject {
@objc dynamic var someProperty: Int
init(someProperty: Int) {
self.someProperty = someProperty
}
}
let c = SomeClass(someProperty: 10)
c.observe(\.someProperty) { object, change in
// ...
}
var index = 2
let path = \[String].[index]
let fn: ([String]) -> String = { strings in strings[index] }
print(greetings[keyPath: path])
// Prints "bonjour"
print(fn(greetings))
// Prints "bonjour"
// Setting 'index' to a new value doesn't affect 'path'
// 如果想要影响, 应该再设置一遍 path = \[String].[index]
index += 1
print(greetings[keyPath: path])
// Prints "bonjour"
// Because 'fn' closes over 'index', it uses the new value
print(fn(greetings))
// Prints "안녕"
代码:
struct ContentView: View {
@State private var data = [Int]()
var body: some View {
List(data, id: \.self) { item in
Text(item)
}
.onAppear {
// 在视图首次显示时加载数据
self.data = [1, 2, 3, 4, 5]
}
}
}
在 SwiftUI 中,\ 是一个符号,用于引用当前的视图或属性。
如果不使用 \ 符号,则需要使用 self.data 来引用当前视图的 data 属性。例如,以下代码与上述代码等效:
struct ContentView: View {
@State private var data = [Int]()
var body: some View {
List(data, id: self.data) { item in
Text(item)
}
.onAppear {
// 在视图首次显示时加载数据
self.data = [1, 2, 3, 4, 5]
}
}
}
在 https://docs.swift.org/swift-book/documentation/the-swift-programming-language/expressions#Key-Path-Expression 中有这种表达式的详细说明.
Key-Path 表达式的意义
在 JS 中, 我们常会用到这样的代码:
而在 Swift 中, 实现类似功能的方法为 Key-Path 表达式.
不过从上述例子中我们也能看到, Swift 为了保证后续使用 path 时的类型安全, 在定义 pathToProperty 时已经推断类型为
WritableKeyPath<User, String>
, 而不是 WritableKeyPath<User, String or Int>.根据上下文省略类型的 Key-Path 表达式
Key-Path 表达式有两大部分组成:
其中, 前者在上下文充分时是可以省略的.
比如官方例子中:
在对 c.observe 传参的时候, 我们只希望传入 "路径", 类型对于这个方法来说是已知的, 就是 Self. 此时可以省略.
Key-Path 是一个表达式, 而不会实时计算
代码:
在 SwiftUI 中,\ 是一个符号,用于引用当前的视图或属性。
如果不使用 \ 符号,则需要使用 self.data 来引用当前视图的 data 属性。例如,以下代码与上述代码等效:
使用 \ 符号可以使代码更简洁、更易于阅读。