我觉得对于真正简单的事情我走得太远了。使用以下代码,我得到的错误是:Cannot invoke 'decode' with an argument list of type '(GameOfLife.Cell, forKey: GameOfLife.Cell.CodingKeys)'
extension GameOfLife {
enum Cell: Equatable, Codable {
case alive
case born
case dying
case dead
var isAlive: Bool {
switch self {
case .alive, .born: return true
case .dying, .dead: return false
}
}
var isDead: Bool {
switch self {
case .alive, .born: return false
case .dying, .dead: return true
}
}
func equalTo(_ rhs: Cell) -> Bool {
switch (self) {
case .alive, .born:
return rhs.isAlive
case .dead, .dying:
return rhs.isDead
}
}
init(_ living: Bool) {
self = living ? .alive : .dead
}
enum CodingKeys: CodingKey {
case alive
case born
case dying
case dead
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
do {
let leftValue = try container.decode(GameOfLife.Cell.alive, forKey: CodingKeys.alive)
self = GameOfLife.Cell.alive
} catch {
let leftValue = try container.decode(GameOfLife.Cell.born, forKey: CodingKeys.born)
self = GameOfLife.Cell.born
} catch {
let leftValue = try container.decode(GameOfLife.Cell.dying, forKey: CodingKeys.dying)
self = GameOfLife.Cell.dying
} catch {
let leftValue = try container.decode(GameOfLife.Cell.dead, forKey: CodingKeys.dead)
self = GameOfLife.Cell.dead
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case .alive:
try container.encode("alive", forKey: .alive)
case .born:
try container.encode("born", forKey: .born)
case .dying:
try container.encode("dying", forKey: .dying)
case .dead:
try container.encode("dead", forKey: .dead)
}
}
}
}
答案 0 :(得分:1)
decode(
的第一个参数是解码对象的预期类型。在对枚举用例进行编码时,String
应该是String
let leftValue = try container.decode(String.self, forKey: .alive) // The compiler can infer the type `CodingKeys`
但是整个init(from
方法都没有意义。如果catch
表达式内发生错误,则不会在随后的catch
表达式中捕获错误。
要将枚举大小写编码为String
,只需将enum
的原始类型声明为String
,然后删除CodingKeys以及init(from
和encode(to
方法。如果要采用Equatable,则必须实现==
extension GameOfLife : Codable {
enum Cell: String, Equatable, Codable {
case alive, born, dying, dead
var isAlive: Bool {
switch self {
case .alive, .born: return true
case .dying, .dead: return false
}
}
// isDead can be simplified
var isDead: Bool {
return !isAlive
}
static func == (lhs: Cell, rhs: Cell) -> Bool {
switch (lhs.isAlive, rhs.isAlive) {
case (true, true), (false, false): return true
default: return false
}
}
init(_ living: Bool) {
self = living ? .alive : .dead
}
}
}