我想更好地理解SWIFT关键路径:
答案 0 :(得分:0)
让我们从这些结构开始:
struct Pet {
var name: String
}
struct Address {
var postcode: String
}
struct Person {
var name: String
var age: Int
var address: Address
var possessions: [String]
var pets: [Pet]
}
和这些变量:
let john = Person(
name: "John",
age: 50,
address: Address(postcode: "BS1 9ZZ"),
possessions: [ "Book",
"Laptop" ],
pets: [ Pet(name: "Linga"),
Pet(name: "Pharaoh") ]
)
let addresses: [Address] = [ Address(postcode: "ABC"),
Address(postcode: "DEF") ]
1)创建包括多个级别的键路径
print("Field")
print(john[keyPath: \Person.name]) // John
print(john[keyPath: \Person.possessions]) // ["Book", "Laptop"]
print("Nested fields")
print(john[keyPath: \Person.address.postcode]) // BS1 9ZZ
2)创建下标成数组的键路径
print("Array lookup")
print(addresses[keyPath: \[Address][1] ]) // Address(postcode: "DEF")
print("Multilevel with array")
print(john[keyPath: \Person.possessions[1]]) // Laptop
print(john[keyPath: \Person.pets[0].name]) // Linga
print("Multilevel using normal indexing")
print(john[keyPath: \Person.possessions][1]) // Laptop
print(john[keyPath: \Person.pets][0][keyPath: \Pet.name]) // Linga
3)一起加入关键路径
print("Join keypaths")
let kp1: KeyPath<Person, Address> = \Person.address
let kp2: KeyPath<Address, String> = \Address.postcode
let kpboth = kp1.appending(path: kp2)
print(john[keyPath: kpboth])
print("Join keypaths including array")
let kpa = \Person.pets
let kpb = \[Pet][0]
let kpc = \Pet.name
let kpall = kpa.appending(path: kpb).appending(path: kpc)
print(john[keyPath: kpall]) // Linga
print("Join keypaths inline")
print(john[keyPath: (\Person.pets).appending(path: (\[Pet][0])).appending(path: (\Pet.name))]) // Linga
4)了解键路径的类型
键路径的类型为:
KeyPath<FromType, ToType>
其中FromType是输入类型,而ToType是输出类型。
所以键路径的类型:\ Person.pets是
KeyPath<Person, [Pet]>
因为这始于一个Person并找到了Pets数组。
同样,KeyPath的类型:[Pet] [0]是:
KeyPath<[Pet],Pet>
因为这是从Pets数组开始并找到一个Pet。
加入键路径时,左侧键路径的输出类型必须与右侧键路径的输入类型匹配。 如果我们重复前面的示例,但显示显式类型,我们可以清楚地看到这一点:
print("Join keypaths including array with Explicit Types")
let kpA: KeyPath<Person, [Pet] > = \Person.pets
let kpB: KeyPath<[Pet], Pet > = \[Pet][0]
let kpC: KeyPath<Pet, String> = \Pet.name
let kpALL = kpA.appending(path: kpB).appending(path: kpC)
print(john[keyPath: kpALL]) // Linga