列出枚举中的所有案例

安全而不是简单

Swift语言的设计重点是“默认安全”方法(不要与“设计安全”混为一谈-Swift不会阻止您进行危险的动作,而只是鼓励良好的做法)。 这种激励措施之一是分别对sum和product数据类型enumstruct的大力支持。 这些类型很好地限制了编译期间潜在状态的数量,因此我们不必编写不应该发生的案例的任何单元测试-您绝对希望永远不要达到给定状态,而不是使用明显的单元测试来覆盖它。

问题陈述

尽管枚举在我们的工具箱中是非常强大的功能,但您可能会发现,没有简单安全的方法来列出enum中的所有情况(当然,这是一个没有关联值的枚举)。 我遇到了一个问题,提出了一个UI选择器,其中包含用户可以选择的所有潜在状态(建模为枚举)。 我只需要一个数组,但是Swift不能立即提供它,而swift-evolving提案仍在等待轮流进行审查(详细讨论及其历史记录都在这里)。

解决方法

Swift社区经常建议两种解决方法来解决我的问题(灵感来自https://theswiftdev.com/2017/01/05/18-swift-gist-generic-allvalues-for-enums/):

  • 使一个enumInt表示,并增加一个计数器,直到无法再创建案例为止:
  • 将原始内存表示形式转换为枚举案例

这两种变通方法都不是理想的:首先假设开发人员为所有枚举分配后续值(从此处开始为1 ),而第二种解决方案可能会在Swift更改枚举内存表示时中断(在Swift中我们仍然缺乏ABI稳定性)。

在本文中,我希望介绍另一种列出所有枚举实例的技术,该技术安全且独立于Swift实现细节。

TLDR;
为此,我们可以 为您的枚举 定义专用的 RawRepresentable 类型,并使该类型可通过 String Int 文字表示。 请记住,如果我们尝试使用 init(rawValue:) 初始化一个枚举 ,则Swift会 init(rawValue:) 所有值 (具有相应的大小写),并将其与 rawValue 进行比较, 直到找到相等的值。 因此,如果我们尝试使用 任何不匹配任何大小写的 rawValue 进行初始化 ,我们将有机会在 == 运算符实现中 收集具有相应枚举的所有rawValues