我认为我最喜欢Swift 4.2的可能是编译器自动为枚举生成一个 allCases的集合。
如何知道在我的枚举里有多少个Case
知道一个枚举有多少种情况或者去迭代所有的情况这通常是很有用的。在Swift4.2之前,你也许使用一个元编程工具例如Sourcery或者手动的维护这个集合
enum Direction {
case left
case right
}
extension Direction {
static let allItems: [Direction] = [.left, .right]
}
Direction.allItems.count
// 2
Direction.allItems.forEach { print($0) }
// left
// right
手动维护是痛苦的,而且当我为枚举添加额外的Cases,而忘记更新allItems的实现时,他无法按照预期工作
enum Direction {
case left
case right
case up
case down
}
Direction.allItems.count
// 2 ???
CaseIterable 协议
Swift4.2为我们带来了CaseIterable协议。他们像Equatable,Comparable和Hashable都是通过编译器自动合成来实现的
你需要做的就是声明你的枚举遵循这个协议
enum Direction: CaseIterable {
case left
case right
case up
case down
}
编译器提供给你一个包含所有情况叫做allCases
的集合
Direction.allCases.count
// 4
Direction.allCases.forEach { print($0) }
// left right up down.
注意:
集合的顺序遵循枚举声明的顺序。
编译器不会自动为具有关联值得枚举合成
allCases
的实现,因为他可能具有无限数量的情况-
文档中仍然要求你必须定义枚举的时候遵循这个协议,但在Swift4.2中不再是这样,只要在同一个文件中,就可以在扩展中声明一致性:
swift4.2之后
enum Direction { ... } extension Direction: CaseIterable {}
swift4.2之前
enum Direction: CaseIterable { ... }
你可以自己实现CaseIterable协议,缺点是如果有人向枚举添加新的case,那么你将维护返回的实现并使其保持最新状态