我使用struct MyThing:Codable { }
解析JSON了几次。现在,我想使用class
而不是struct
,因为struct
并不真正适合我需要完成的工作(可变性,一致性等),还有一些子类化。我尝试过:
class Beverage:Codable{
var name:String = ""
}
class Beer:Beverage{
var alcoholPercent:Double = 0
}
我不一定会在同一列表中收到多种不同类型的饮料的列表,比方说,我只想解码[Beer]
的列表。如果我将json与单一啤酒(如{"name": "Hansa", "alcoholPercent": 5.4}
一起尝试,并尝试将其解码为Beer类,如下所示:
let beer = try! JSONDecoder().decode(Beer.self, from: json.data(using: .utf8)!)
beer
将具有name: Hansa
和alcoholPercent: 0.0
。名称正确,但是alcoholPercent是该类中的默认值。
有没有一种神奇的方法可以使子类自动符合Codable
而无需显式设置每个变量的键/值?
此有效:
class Beverage:Codable{
var name:String = ""
}
class Beer:Beverage{
var alcoholPercent:Double = 0
enum CodingKeys:String, CodingKey{
case alcoholPercent
}
required init(from decoder: Decoder) throws {
let values = try! decoder.container(keyedBy: CodingKeys.self)
self.alcoholPercent = try! values.decode(Double.self, forKey: .alcoholPercent)
try super.init(from: decoder)
}
}
使用此代码,我得到"Hansa"
和5.4
。
为什么对于子类我必须显式遵循Codable
,而对于基类却不必显式地遵循'--
呢?没有所有手册代码,有没有办法做到这一点?我觉得这应该可以直接使用,而不需要必需的init。
答案 0 :(得分:3)
您要提供的是init(from:)
中Beer
覆盖的编译器综合。 Swift不会那样做。这已在Swift论坛上进行了讨论,例如in this thread。 Itai Ferber是负责Codable
设计和实施的主要Apple工程师,因此您可以认为他的回答具有权威性。
如果从Codable
中删除Beverage
符合性,并将其直接添加到Beer
(以及添加到Beverage
的任何其他叶子类中),则可能会得到以下行为:想。不过,只有在您不需要Beverage
本身的一致性时,这种方法才有用。