Swift中如何声明支持扁平化switch匹配的嵌套枚举?
回答
这个效果无法通过普通自定义枚举实现,是Swift编译器为Optional类型单独提供的特供语法糖,没有对外提供通用的开启方式。
- Optional的扁平化匹配逻辑是硬编码在编译器中的:你看到的可以直接用内层枚举case匹配
Optional<枚举类型>的写法,本质是编译器自动帮你补全了.some(内层case)的完整匹配路径,这个逻辑只对Swift.Optional类型生效,不属于枚举的通用特性。 - 把外层枚举的关联值case命名为
.some也无法获得相同能力:哪怕你把自定义泛型枚举定义为和Optional结构完全一致的enum Foo<T> { case none, some(T) },编译器也不会为它触发隐式的扁平化匹配转换,你仍然需要显式写.some(.yep)才能匹配到关联值的内层case。 - 目前没有公开的注解可以为自定义枚举开启这个能力。
如果你需要近似的使用体验,可以通过重载模式匹配运算符~=实现有限的简化,示例如下:
// 自定义模式匹配规则 extension Foo where Bar: Equatable { static func ~= (pattern: Bar, value: Foo<Bar>) -> Bool { guard case .dope(let innerValue) = value else { return false } return innerValue == pattern } } // 此时可以这么写 switch b { case .nope: break case Baz.yep: break }
如果要实现完全省略内层枚举前缀的.yep写法,需要针对每一个内层枚举的case给外层枚举做静态属性扩展,无法通用自动生成,实际使用成本很高,和Optional的原生体验有较大差距。
内容的提问来源于stack exchange,提问作者Isaaс Weisberg
相关产品推荐
相关产品推荐

