[英]golang's fallthrough seems unexpected
我有以下代碼:
package main
import (
"fmt"
)
func main() {
switch {
case 1 == 1:
fmt.Println("1 == 1")
fallthrough
case 2 == 1:
fmt.Println("2 == 1")
}
}
在操場上打印兩條線 - 請參見此處的示例 。 我本來期望這個通過聲明包括評估下一個case
陳述,但似乎並非如此。
當然,我總是可以使用一堆if
語句,所以這不是一個真正的障礙,但我很好奇這里的意圖是什么,因為在我看來這是一個非顯而易見的結果。
有人在乎解釋嗎? 例如:在此代碼中,如何執行第1和第3個案例?
據推測,Go的墮落行為是以C為模型的,C總是像這樣工作。 在C, switch
語句,如果它是這樣寫的Goto條件的,所以你的具體的例子會被編譯鏈只是速記:
# Pseudocode
if 1 == 1 goto alpha
if 2 == 1 goto beta
alpha:
fmt.Println("1 == 1")
beta:
fmt.Println("2 == 1")
正如您所看到的,一旦執行進入alpha
情況,它就會繼續向下流動,忽略beta
標簽(因為標簽本身並沒有真正做任何事情)。 條件檢查已經發生,不會再發生。
因此,fallthrough switch
語句的非直觀性質僅僅是因為switch
語句是goto語句。
Switch不是一堆ifs。 它更類似於if {} else if {}
構造,但有幾個曲折 - 即break
和fallthrough
。 切換執行第一種和第三種情況是不可能的 - 交換機不會檢查每個條件,它會找到第一個匹配並執行它。 就這樣。
它的主要目的是遍歷可能值的列表並為每個值執行不同的代碼。 事實上,在C(其中switch語句來自)中,switch表達式只能是整數類型,case case值只能是switch表達式也將被比較的常量。 僅在最近,語言才開始在交換機案例中添加對字符串,布爾表達式等的支持。
至於通過邏輯,它也來自C.在C中沒有穿透運算符。在C執行進入下一種情況(不檢查大小寫值),除非遇到break操作符。 這種設計的原因是,有時您需要做一些特殊的事情,然后執行與其他情況相同的步驟。 所以,這種設計只允許這樣。 不幸的是,它很少有用,所以默認情況下,當程序員忘記放入一個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")
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.