Swift:切换声明的通过行为

时间:2015-09-02 02:20:22

标签: swift switch-statement

目前我有这个:

let somePoint = (1, 0)

switch somePoint {
case (0,0):
    print("origin") // does not print
    fallthrough
case (_, 0):
    print("y-axis") // prints y-axis. this makes sense
    fallthrough
case(0, _):
    print("x-axis") // prints x-axis (because of fallthrough? this should not print)
    fallthrough
case(-2...2, -2...2):
    print("in 5x5 box about the origin") // this prints and makes sense
default:
    print("somewhere else") // does not print
}

我对这个开关语句的目标是,如果每个案例都为真,则打印每个案例,而不是只有第一个匹配打印的案例。我以为我可以通过这个演绎声明来做到这一点。但是,这让我怀疑它是如何工作的。即使案例不匹配,为什么fallthrough会自动打印下一个案例?我怎样才能使这个switch语句以我想要的方式工作?

2 个答案:

答案 0 :(得分:7)

Fallthrough进入下一个案例,而不是下一个匹配案例。该概念继承自C switch语句,其中每个case可被视为goto目标标签,switch语句将执行带入第一个匹配的语句。

在C中,switch语句仅指示块内执行启动的位置。为了方便起见,可以使用break语句跳过switch身体的其余部分,但没有任何东西强迫你;如果不这样做,执行会继续正常进行,就像case不存在一样。例如:

switch (countdown)
{
    case 3: puts("3...");
    case 2: puts("2...");
    case 1: puts("1...");
    case 0: puts("0!");
}

在任何地方都没有break,如果countdown是3,那么你得到的全部内容(即使countdown显然是3,而不是2,1或0)。

当执行从一个案例转到另一个案例而不是退出switch范围(例如,使用break语句)时,你会得到“堕落”(这就是Swift {{1关键字确实)。

这与C相关,因为您可以在fallthrough语句中使用任意复杂的结构,如果需要可以重叠。这是一个合法的C程序:

switch

然而,这种使用非常罕见并且通常难以遵循(快速!如果switch (x) { case 0: if (y == 3) { case 1: puts("hello"); } else { puts("world"); } case 2: puts("!"); } 可以执行else分支吗?)。我没有测试过,但是如果你能用Swift做类似的话,我会非常惊讶。

一般来说,在C中,跌倒被认为是不好的风格,因为通常很难判断跌倒是自愿的还是由于缺少x == 1陈述。 Swift使用break语句解决了这个问题,这使得您明确希望执行继续执行fallthrough语句中的下一个案例,而不是退出switch范围。

在您的情况下,您不能使用fallthrough来获得您想要的内容,因为只有在您需要的执行顺序是线性时,才能使用fallthrough。您需要跳过无效的代码块,因此需要使用switch序列而不是if-else语句。

答案 1 :(得分:3)

如果您希望查看其他匹配的案例而非下一个案例(如fallthrough那样),则switch不适合该作业。

相反,您应该使用一系列if语句,例如:

Bool gotOne = false;
if (somePoint.0 == 0 && somepoint.1 == 0) {
    print("origin")
    gotOne = true;
}
if (somepoint.1 == 0) {
    print("y-axis")
    gotOne = true;
}
if (somepoint.0 == 0) {
    print("x-axis")
    gotOne = true;
}
:
if (! gotOne) {
    print("somewhere else")
}