前语
Swift 中的枚举很强大,算是一等公民。能够界说函数,也能够恪守协议、完成 extension 等等。
相关值也是 Swift 枚举的一大特性。根本用法如下:
enum RequestResult {
case success
case failure(Error)
}
let result = RequestResult.failure(URLError(URLError.timedOut))
switch result {
case .success:
print("请求成功")
case .failure(let error):
print(error)
}
1、在需求相关值的 case 中声明相关值的类型。
2、在 switch 的 case 中声明一个常量或者变量来接收。
遇到的问题
一般状况下,上述的代码是明晰明了的。但在实践开发的过程中,遇到了以下的状况:相关值的类型也是枚举,并且嵌套不止一层。
比方下面的代码:
enum EnumT1 {
case test1(EnumT2)
case other
}
enum EnumT2 {
case test2(EnumT3)
case other2
}
enum EnumT3 {
case test3(EnumT4)
case test4
}
依据咱们的需求,需求进行屡次嵌套来进行类型细化。当进行枚举的声明时,代码仍是正常的,简单明了。但当进行 case 判别时,代码就变得丑陋难写了。
比方,我只想处理 EnumT3 中的 test4 的状况,在 switch 中我需求进行 switch 的嵌套来处理:
let t1: EnumT1? = .test1(.test2(.test4))
switch t1 {
case .test1(let t2):
switch t2 {
case .test2(let t3):
switch t3 {
case .test4:
print("test4")
case default:
print("default")
}
default:
print("default")
}
default:
print("default")
}
这种写法,对于一个程序员来说是无法忍受的。它存在两个问题:一是代码臃肿,我的本意是只处理某一种状况,但我需求显式的嵌套多层 switch;二是枚举本身是不引荐运用 default
的,官方引荐是显式的写出一切的 case,以防呈现难以预料的问题。
废话不多说,下面开始简化之路。
实践一
首先能想到的是,由于是对某一种状况进行处理,考虑运用 if + ==
的判别来进行处理,比方下面这种写法:
if t1 == .test1(.test2(.test4)) { }
这样处理有两个不足之处。首先,假如对枚举用 ==
操作符的话,需求对每一个枚举都恪守 Equatable 协议,这为咱们带来了工作量。其次最重要的是,这种处理方式无法应对 test3 这种带有相关值的状况。
if t1 == .test1(.test2(.test3) { }
假如这样写的话,编译器会报错,由于 test3 是需求传进去一个 Int 值的。
if t1 == .test1(.test2(.test3(20))) { }
假如这样写的话也不可,由于咱们的需求是处理 test3 的统一状况(一切的相关值),而不是某一个详细的相关值。
实践二
通过在网上的一番搜寻,发现能够用 if-case
关键字来简化写法:
if case .test1(.test2(.test3)) = t1 { }
这样就能统一处理 test3 这个 case 的一切状况了。假如想获取相关值,能够用下面的写法:
if case .test1(.test2(.test3(let i))) = t1 {
print(i)
}
比照上面的 switch 写法,能够看到,下面的这种写法既易懂又好写。
总结来说,当咱们遇到相关值多层枚举嵌套的时候,又需求对某一种状况进行处理。那么能够选用实践二的做法来进行代码简化。
参考链接
- 官方文档
- stackoverflow