我有以下代码:
package main
import (
"fmt"
)
func main() {
switch {
case 1 == 1:
fmt.Println("1 == 1")
fallthrough
case 2 == 1:
fmt.Println("2 == 1")
}
}
在go操场上打印两条线 - see example here。我本来期望通过声明来包括对下一个case
声明的评估,但似乎并非如此。
当然,我总是可以使用一堆if
语句,所以这不是一个真正的障碍,但我很好奇这里的目的是什么,因为在我看来这是一个非显而易见的结果
有人在乎解释吗?例如:在this代码中,如何执行第1和第3个案例?
答案 0 :(得分:3)
“fallthrough”语句将控制转移到表达式“switch”语句中的下一个case子句的第一个语句。它只能用作这种子句中的最终非空语句。
这似乎完美地描述了你观察到的行为。
答案 1 :(得分:3)
据推测,Go的堕落行为是以C为模型的,C总是像这样工作。在C语言中,switch
语句只是条件格式链的缩写,因此您的特定示例将被编译为,就好像它的编写方式一样:
# Pseudocode
if 1 == 1 goto alpha
if 2 == 1 goto beta
alpha:
fmt.Println("1 == 1")
beta:
fmt.Println("2 == 1")
正如您所看到的,一旦执行进入alpha
案例,它就会继续流下来,忽略beta
标签(因为标签本身并没有真正做任何事情)。条件检查已经发生,并且不会再次发生。
因此,初级switch
语句的非直观性质仅仅是因为switch
语句是goto语句的简洁。
答案 2 :(得分:2)
Switch不是一堆ifs。它更类似于if {} else if {}
构造,但有几个曲折 - 即break
和fallthrough
。切换不执行第一种和第三种情况是不可能的 - 交换机不会检查每个条件,它会找到第一个匹配并执行它。这就是全部。
它的主要目的是遍历可能值列表并为每个值执行不同的代码。事实上,在C(其中switch语句来自)中,switch表达式只能是整数类型,case case值只能是switch表达式也将被比较的常量。仅在最近才开始,语言开始在交换机情况下添加对字符串,布尔表达式等的支持。
关于通过逻辑,它也来自C.在C中没有穿透运算符。在C执行进入下一种情况(不检查大小写值),除非遇到break操作符。这种设计的原因是,有时您需要做一些特殊的事情,然后执行与其他情况相同的步骤。所以,这种设计只允许这样。不幸的是,它很少有用,所以默认情况下,当程序员忘记放入一个中断语句时会导致更多麻烦,然后实际上帮助真正省略故意破坏。因此,许多现代语言将此逻辑更改为默认情况下永远不会失败,并且如果实际需要掉线则需要明确的通过语句。
不幸的是,很难想出一个非常有用的堕落实例,它很短,足以适应答案。正如我所说,它相对罕见。但有时您需要编写类似于此的代码:
if x == a || x == b {
if x == a {
// do action a
}
// do action ab
} else if x == c {
// do action c
} else if x == d {
// do action d
}
事实上,我最近在一个项目中需要类似结构的代码。所以,我使用了switch语句。它看起来像这样:
switch x {
case a: // do action a
fallthrough
case b: // do action ab
case c: // do action c
case d: // do action d
}
你从这个问题的转换在功能上等同于:
if 1 == 1 || 2 == 1 {
if 1 == 1 {
fmt.Println("1 == 1")
}
fmt.Println("2 == 1")
}