Swift Keypath:如何将它们连接在一起并引用数组?

时间:2019-09-26 13:05:10

标签: arrays swift append keypaths

我想更好地理解SWIFT关键路径:

  1. 创建包含多个级别的键路径
  2. 创建下标到数组的键路径
  3. 将关键路径结合在一起
  4. 了解键路径的类型

1 个答案:

答案 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