if 是用于測(cè)試某個(gè)條件(布爾型或邏輯型)的語(yǔ)句,如果該條件成立,則會(huì)執(zhí)行 if 后由大括號(hào)括起來(lái)的代碼塊,否則就忽略該代碼塊繼續(xù)執(zhí)行后續(xù)的代碼。
if condition {
// do something
}
如果存在第二個(gè)分支,則可以在上面代碼的基礎(chǔ)上添加 else 關(guān)鍵字以及另一代碼塊,這個(gè)代碼塊中的代碼只有在條件不滿足時(shí)才會(huì)執(zhí)行。if 和 else 后的兩個(gè)代碼塊是相互獨(dú)立的分支,只可能執(zhí)行其中一個(gè)。
if condition {
// do something
} else {
// do something
}
如果存在第三個(gè)分支,則可以使用下面這種三個(gè)獨(dú)立分支的形式:
if condition1 {
// do something
} else if condition2 {
// do something else
} else {
// catch-all or default
}
else-if 分支的數(shù)量是沒(méi)有限制的,但是為了代碼的可讀性,還是不要在 if 后面加入太多的 else-if 結(jié)構(gòu)。如果你必須使用這種形式,則把盡可能先滿足的條件放在前面。
即使當(dāng)代碼塊之間只有一條語(yǔ)句時(shí),大括號(hào)也不可被省略(盡管有些人并不贊成,但這還是符合了軟件工程原則的主流做法)。
關(guān)鍵字 if 和 else 之后的左大括號(hào) {
必須和關(guān)鍵字在同一行,如果你使用了 else-if 結(jié)構(gòu),則前段代碼塊的右大括號(hào) }
必須和 else-if 關(guān)鍵字在同一行。這兩條規(guī)則都是被編譯器強(qiáng)制規(guī)定的。
非法的 Go 代碼:
if x{
}
else { // 無(wú)效的
}
要注意的是,在你使用 gofmt
格式化代碼之后,每個(gè)分支內(nèi)的代碼都會(huì)縮進(jìn) 4 個(gè)或 8 個(gè)空格,或者是 1 個(gè) tab,并且右大括號(hào)與對(duì)應(yīng)的 if 關(guān)鍵字垂直對(duì)齊。
在有些情況下,條件語(yǔ)句兩側(cè)的括號(hào)是可以被省略的;當(dāng)條件比較復(fù)雜時(shí),則可以使用括號(hào)讓代碼更易讀。條件允許是符合條件,需使用 &&、|| 或 !,你可以使用括號(hào)來(lái)提升某個(gè)表達(dá)式的運(yùn)算優(yōu)先級(jí),并提高代碼的可讀性。
一種可能用到條件語(yǔ)句的場(chǎng)景是測(cè)試變量的值,在不同的情況執(zhí)行不同的語(yǔ)句,不過(guò)將在第 5.3 節(jié)講到的 switch 結(jié)構(gòu)會(huì)更適合這種情況。
示例 5.1 booleans.go
package main
import "fmt"
func main() {
bool1 := true
if bool1 {
fmt.Printf("The value is true\n")
} else {
fmt.Printf("The value is false\n")
}
}
輸出:
The value is true
注意事項(xiàng) 這里不需要使用 if bool1 == true
來(lái)判斷,因?yàn)?bool1
本身已經(jīng)是一個(gè)布爾類型的值。
這種做法一般都用在測(cè)試 true
或者有利條件時(shí),但你也可以使用取反 !
來(lái)判斷值的相反結(jié)果,如:if !bool1
或者 if !(condition)
。后者的括號(hào)大多數(shù)情況下是必須的,如這種情況:if !(var1 == var2)
。
當(dāng) if 結(jié)構(gòu)內(nèi)有 break、continue、goto 或者 return 語(yǔ)句時(shí),Go 代碼的常見寫法是省略 else 部分(另見第 5.2 節(jié))。無(wú)論滿足哪個(gè)條件都會(huì)返回 x 或者 y 時(shí),一般使用以下寫法:
if condition {
return x
}
return y
注意事項(xiàng) 不要同時(shí)在 if-else 結(jié)構(gòu)的兩個(gè)分支里都使用 return 語(yǔ)句,這將導(dǎo)致編譯報(bào)錯(cuò) function ends without a return statement
(你可以認(rèn)為這是一個(gè)編譯器的 Bug 或者特性)。( 譯者注:該問(wèn)題已經(jīng)在 Go 1.1 中被修復(fù)或者說(shuō)改進(jìn) )
這里舉一些有用的例子:
if str == "" { ... }
if len(str) == 0 {...}
判斷運(yùn)行 Go 程序的操作系統(tǒng)類型,這可以通過(guò)常量 runtime.GOOS
來(lái)判斷(第 2.2 節(jié))。
if runtime.GOOS == "windows" {
. ..
} else { // Unix-like
. ..
}
這段代碼一般被放在 init() 函數(shù)中執(zhí)行。這兒還有一段示例來(lái)演示如何根據(jù)操作系統(tǒng)來(lái)決定輸入結(jié)束的提示:
var prompt = "Enter a digit, e.g. 3 "+ "or %s to quit."
func init() {
if runtime.GOOS == "windows" {
prompt = fmt.Sprintf(prompt, "Ctrl+Z, Enter")
} else { //Unix-like
prompt = fmt.Sprintf(prompt, "Ctrl+D")
}
}
函數(shù) Abs()
用于返回一個(gè)整型數(shù)字的絕對(duì)值:
func Abs(x int) int {
if x < 0 {
return -x
}
return x
}
isGreater
用于比較兩個(gè)整型數(shù)字的大小:
func isGreater(x, y int) bool {
if x > y {
return true
}
return false
}
在第四種情況中,if 可以包含一個(gè)初始化語(yǔ)句(如:給一個(gè)變量賦值)。這種寫法具有固定的格式(在初始化語(yǔ)句后方必須加上分號(hào)):
if initialization; condition {
// do something
}
例如:
val := 10
if val > max {
// do something
}
你也可以這樣寫:
if val := 10; val > max {
// do something
}
但要注意的是,使用簡(jiǎn)短方式 :=
聲明的變量的作用域只存在于 if 結(jié)構(gòu)中(在 if 結(jié)構(gòu)的大括號(hào)之間,如果使用 if-else 結(jié)構(gòu)則在 else 代碼塊中變量也會(huì)存在)。如果變量在 if 結(jié)構(gòu)之前就已經(jīng)存在,那么在 if 結(jié)構(gòu)中,該變量原來(lái)的值會(huì)被隱藏。最簡(jiǎn)單的解決方案就是不要在初始化語(yǔ)句中聲明變量(見 5.2 節(jié)的例 3 了解更多)。
示例 5.2 ifelse.go
package main
import "fmt"
func main() {
var first int = 10
var cond int
if first <= 0 {
fmt.Printf("first is less than or equal to 0\n")
} else if first > 0 && first < 5 {
fmt.Printf("first is between 0 and 5\n")
} else {
fmt.Printf("first is 5 or greater\n")
}
if cond = 5; cond > 10 {
fmt.Printf("cond is greater than 10\n")
} else {
fmt.Printf("cond is not greater than 10\n")
}
}
輸出:
first is 5 or greater cond is not greater than 10
下面的代碼片段展示了如何通過(guò)在初始化語(yǔ)句中獲取函數(shù) process()
的返回值,并在條件語(yǔ)句中作為判定條件來(lái)決定是否執(zhí)行 if 結(jié)構(gòu)中的代碼:
if value := process(data); value > max {
...
}