可解码,不解码具有无效值的可选枚举

Has*_*jmi 6 swift swift4 codable

我已经定义了一个这样的枚举:

enum ClubLevel: Int, Codable {
    case golden = 1, silver, bronze
}
Run Code Online (Sandbox Code Playgroud)

在我的结构中,我有一个type的可选属性,ClubLevel当我在中解码该属性时init(from decoder: Decoder)

self.clubLevel = try container.decode(ClubLevel?.self, forKey: .clubLevel)
Run Code Online (Sandbox Code Playgroud)

我遇到这个错误:

debug描述: "Cannot initialize ClubLevel from invalid Int value 0", underlyingError: nil"

我想知道即使这个属性是可选的,解码器也不会继续

任何的想法?

Ham*_*ish 10

线

self.clubLevel = try container.decode(ClubLevel?.self, forKey: .clubLevel)
Run Code Online (Sandbox Code Playgroud)

不会尝试解码ClubLevelnil如果失败则分配。它的作用是:

  1. 尝试对密钥进行解码nil(在JSON中以表示nullclubLevel。如果不成功,
  2. 尝试解码ClubLevelclubLevel关键。如果不成功,
  3. 引发错误

因此,如果clubLevel键的值既不是nil也不是有效的ClubLevel表示形式,则会引发错误。您会注意到,这也意味着如果clubLevel键完全丢失(而不是值出现nil),则会引发错误。

忽略丢失的键是通过完成decodeIfPresent

self.clubLevel = try container.decodeIfPresent(ClubLevel.self, forKey: .clubLevel)
Run Code Online (Sandbox Code Playgroud)

现在将:

  1. nil如果clubLevel容器中缺少密钥,则返回。如果他们存在密钥,
  2. 尝试对密钥进行解码nil(在JSON中以表示nullclubLevel。如果不成功,
  3. 尝试解码ClubLevelclubLevel关键。如果不成功,
  4. 引发错误

这是在编译器生成的实现中对可选变量进行解码的默认行为init(from:)。由于clubLevel键的值无效,因此仍然会引发错误ClubLevel

如果您只想解码ClubLevelnil则由于某种原因(键丢失,无效值等)而分配失败,那么您可以使用try?

self.clubLevel = try? container.decode(ClubLevel.self, forKey: .clubLevel)
Run Code Online (Sandbox Code Playgroud)