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

标签 swift swift4 codable

我定义了这样一个枚举:

enum ClubLevel: Int, Codable {
    case golden = 1, silver, bronze
}

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

self.clubLevel = try container.decode(ClubLevel?.self, forKey: .clubLevel)

我遇到这个错误:

调试描述:“无法从无效的 Int 值 0 初始化 ClubLevel”,underlyingError:nil“

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

有什么想法吗?

最佳答案

线

self.clubLevel = try container.decode(ClubLevel?.self, forKey: .clubLevel)

不尝试解码 ClubLevel,如果不成功则分配 nil。它的作用是:

  1. 尝试为 clubLevel key 解码 nil(在 JSON 中表示为 null)。如果不成功,
  2. 尝试为 clubLevel key 解码 ClubLevel。如果不成功,
  3. 抛出错误

因此,如果 clubLevel 键的值既不是 nil 也不是有效的 ClubLevel 表示,您将抛出错误。您会注意到,这也意味着如果 clubLevel 键完全缺失(而不是以 nil 的值出现),您将得到一个错误抛出。

忽略丢失的键是用decodeIfPresent完成的:

self.clubLevel = try container.decodeIfPresent(ClubLevel.self, forKey: .clubLevel)

现在将:

  1. 如果容器中缺少 clubLevel key ,则返回 nil。如果他们的 key 存在,
  2. 尝试为 clubLevel key 解码 nil(在 JSON 中表示为 null)。如果不成功,
  3. 尝试为 clubLevel key 解码 ClubLevel。如果不成功,
  4. 抛出错误

这是在编译器生成的 init(from:) 实现中解码可选值的默认行为。它仍然会在您的情况下引发错误,因为 clubLevel 键的值不是有效的 ClubLevel

如果你只想尝试解码一个ClubLevel,在由于任何原因( key 丢失,无效值)解码失败时分配nil , 等), 那么你想使用 try?:

self.clubLevel = try? container.decode(ClubLevel.self, forKey: .clubLevel)

关于swift - 可解码,不解码具有无效值的可选枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47906137/

相关文章:

ios - 为什么 Swift4 会转换一个 UIButton 数组!到 [UIButton?] 类型?

swift4 - 在 Swift 4.0 和 Xcode 9.0 中获取用户桌面路径

swift - 如何使用 JSONDecoder 根据顺序键获取排序数据?

json - 使用 Alamofire 和 Codable 进行放置请求

objective-c - Println() 是否在实时应用程序中使用内存?

swift - 在 View 之间传输数据,保存在 UserDefaults 中

ios - 使用平移手势识别器关闭 View Controller

ios - 从 UIViewController 启动 UICollectionView

ios - 如何将图像添加到相机覆盖 View (swift4)

ios - 使用解码协议(protocol)解析 Json (Codable)