【发布时间】:2018-10-16 17:43:30
【问题描述】:
我有 Animal 协议,其中包含 2 个符合它的结构和一个 Farm 结构,用于存储动物列表。然后,我让它们都符合 Codable 以将其存储在一个文件中,但它会抛出错误cannot automatically synthesize 'Encodable' because '[Animal]' does not conform to 'Encodable'
我明白为什么会发生这种情况,但我找不到好的解决方案。如何使数组仅接受 Codable 和 Animal,而不将 Animal 标记为 Codable,这样就不会发生此问题,例如 var animals = [Codable & Animal]? (或任何其他解决方法)。谢谢
protocol Animal: Codable {
var name: String { get set }
var sound: String { get set }
}
struct Cow: Animal {
var name = "Cow"
var sound = "Moo!"
}
struct Duck: Animal {
var name = "Duck"
var sound = "Quack!"
}
struct Farm: Codable {
var name = "Manor Farm"
// this is where the error is shown
var animals = [Animal]()
}
--编辑-- 当我将它们更改为一个类时,它看起来像这样:
class Animal: Codable {
var name = ""
var sound = ""
}
class Duck: Animal {
var beakLength: Int
init(beakLength: Int) {
self.beakLength = beakLength
super.init()
name = "Duck"
sound = "Quack!"
}
required init(from decoder: Decoder) throws {
// works, but now I am required to manually do this?
fatalError("init(from:) has not been implemented")
}
}
如果我没有其他属性,它会起作用,但是一旦我添加了一个,我需要引入一个初始化程序,然后我需要从解码器初始化程序中包含初始化程序,它删除了 Codable 提供的自动转换。因此,要么我为我扩展的每个类手动执行此操作,要么我可以强制转换变量(如var beakLength: Int!)以消除对初始化程序的要求。但是有没有别的办法?这似乎是一个简单的问题,但解决它使它变得非常混乱,我不喜欢。另外,当我使用这种方法从文件中保存/加载时,似乎没有保存数据
【问题讨论】:
-
如何将 Animal 协议更改为一个类,并让 Cow 和 Duck 成为它的子类
-
只需让 Duck 和 Cow Codable 并从 Animal 中删除 Codable
-
没有数组的类型是协议,你可以把Animal改成类和子类
-
@LeoDabus 但随后 Farm 将无法 Codable,因为一旦 Animal 不是,则不能保证数组是 Codable。
-
@NaderBesada 我先试过这个,忘了说。我将更新帖子,说明为什么它不是一个完美的解决方案以及为什么我会看到是否还有其他问题。谢谢
标签: swift codable decodable encodable