3
好像decode(_forKey:)
忽略了它的第一個參數,而是依賴泛型參數來決定要解碼的類型。如果是這種情況,第一個參數是什麼?爲什麼`decode(_:forKey:)`忽略它的第一個參數?
class Cat: Codable {
func speak() -> String { return "Meow" }
}
class Lion: Cat {
override func speak() -> String { return "Roar!" }
}
class Person: Codable {
let firstPet: Cat
let secondPet: Cat
init(firstPet: Cat, secondPet: Cat) {
self.firstPet = firstPet
self.secondPet = secondPet
}
enum CodingKeys: CodingKey { case firstPet, secondPet }
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.firstPet = try container.decode(Lion.self, forKey: .firstPet)
let typeOfCat: Cat.Type = Lion.self
self.secondPet = try container.decode(typeOfCat, forKey: .secondPet)
}
}
let before = Person(firstPet: Lion(), secondPet: Lion())
let after = try! JSONDecoder().decode(Person.self, from: JSONEncoder().encode(before))
after.firstPet.speak() //"Roar!"
after.secondPet.speak() //"Meow" ...really?
第一個參數用於將通用參數專門用於調用。在超類metatype的一個變量中傳遞一個子類metatype的實例並傳遞它是有點奇怪的 - 有沒有什麼具體的事情需要在這裏做,以防止你直接傳入'Lion.self'? –
但是泛型參數可以從調用者用返回值做什麼來推斷,不是嗎? (是的,當然在這個例子中,我可以通過'Lion.self',但是我真正想做的是解碼在運行時確定的各種子類。) – andyvn22
不,不總是 - 有些情況下依賴返回類型可能會導致難以追查的歧義;傳遞一個元類型參數是防止含糊不清的唯一有效方法。代碼可以使用傳入的具體元類型而不是泛型參數,但這是一個非常獨特的用例。不過,您應該可以在運行時切換類型,並使用正確的靜態類型調用解碼。 –