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所有情况下的值? 但是我仍然得到一个错误? 为什么我得到这个错误,我错过了什么?

使用enumtypes时,Swift只能真正validation一个switch块是彻底的。 即使在Bool上打开,除了truefalse之外,还需要一个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值是有点分裂头发…