Swift中切换情况的详尽情况
苹果文档说
每个switch语句都必须是详尽的。 也就是说,所考虑types的每个可能的值必须与其中一个开关情况相匹配。
所以在新的Xcode我已经放置了这样的代码
println(UInt16.min); // Output : '0' println(UInt16.max); // Output : '65535' var quantity : UInt16 = 10; switch quantity { case 0...65535: //OR case UInt16.min...UInt16.max: println(); default: println(); }
现在如果我删除默认部分,我得到一个编译错误,显示交换机必须是详尽的
所以我的问题是,我已经提到的case 0...65535:
我没有提到一个UInt16
所有情况下的值? 但是我仍然得到一个错误? 为什么我得到这个错误,我错过了什么?
使用enum
types时,Swift只能真正validation一个switch
块是彻底的。 即使在Bool
上打开,除了true
和false
之外,还需要一个default
块:
var b = true switch b { case true: println("true") case false: println("false") } // error: switch must be exhaustive, consider adding a default clause
然而,使用enum
,编译器很高兴只看到这两种情况:
enum MyBool { case True case False } var b = MyBool.True switch b { case .True: println("true") case .False: println("false") }
如果你需要为编译器包含一个default
块,但没有任何事情要做,那么break
关键字就派上用场了:
var b = true switch b { case true: println("true") case false: println("false") default: break }
部分原因是你看到这个错误,因为编译器不能在没有运行代码的情况下validation交换机是彻底的。 expression式0...65535
创build一个ClosedInterval
结构,当switch语句执行时,如果值quantity
在间隔中,则必须询问结构。 在运行时有这个改变的空间,所以编译器不能在编译时检查它。 (见停机问题 。)
更一般的情况是,编译器无法检测到整数值的穷尽开关 – 即使为每个整数值( case 0: ... case 1: ... ... case 65535:
添加特定情况,它也不会检测到整数值的穷举开关不知道你的交换机是彻底的。 (理论上它可以,但是:如果这是你想看到的东西,考虑提交关于这个function的请求 。)
现在有两种情况,Swift可以检测到完整性,并允许您省略default
子句:元组中的枚举和值绑定。 @ NateCook的答案涵盖枚举 – 如果您打开一个枚举值,并在您的switch
中的枚举中的每个case
,你不需要default
。 如果您打开一个元组并绑定每个可能的值组合,您也不需要default
标签,如Swift书中所示 :
switch anotherPoint { case (let x, 0): println("on the x-axis with an x value of \(x)") case (0, let y): println("on the y-axis with ay value of \(y)") case let (x, y): println("somewhere else at (\(x), \(y))") }
你可以把这个规则概括为“如果types系统知道你的types的可能值,它可以检测switch
完整性”,但是types系统不知道可能的范围(例如, UInt32
值是有点分裂头发…