for、switch 或 select 語句都可以配合標(biāo)簽(label)形式的標(biāo)識(shí)符使用,即某一行第一個(gè)以冒號(hào)(:
)結(jié)尾的單詞(gofmt 會(huì)將后續(xù)代碼自動(dòng)移至下一行)。
示例 5.13 for6.go:
(標(biāo)簽的名稱是大小寫敏感的,為了提升可讀性,一般建議使用全部大寫字母)
package main
import "fmt"
func main() {
LABEL1:
for i := 0; i <= 5; i++ {
for j := 0; j <= 5; j++ {
if j == 4 {
continue LABEL1
}
fmt.Printf("i is: %d, and j is: %d\n", i, j)
}
}
}
本例中,continue 語句指向 LABEL1,當(dāng)執(zhí)行到該語句的時(shí)候,就會(huì)跳轉(zhuǎn)到 LABEL1 標(biāo)簽的位置。
您可以看到當(dāng) j==4 和 j==5 的時(shí)候,沒有任何輸出:標(biāo)簽的作用對(duì)象為外部循環(huán),因此 i 會(huì)直接變成下一個(gè)循環(huán)的值,而此時(shí) j 的值就被重設(shè)為 0,即它的初始值。如果將 continue 改為 break,則不會(huì)只退出內(nèi)層循環(huán),而是直接退出外層循環(huán)了。另外,還可以使用 goto 語句和標(biāo)簽配合使用來模擬循環(huán)。
示例 5.14 goto.go:
package main
func main() {
i:=0
HERE:
print(i)
i++
if i==5 {
return
}
goto HERE
}
上面的代碼會(huì)輸出 01234
。
使用逆向的 goto 會(huì)很快導(dǎo)致意大利面條式的代碼,所以不應(yīng)當(dāng)使用而選擇更好的替代方案。
特別注意 使用標(biāo)簽和 goto 語句是不被鼓勵(lì)的:它們會(huì)很快導(dǎo)致非常糟糕的程序設(shè)計(jì),而且總有更加可讀的替代方案來實(shí)現(xiàn)相同的需求。
一個(gè)建議使用 goto 語句的示例會(huì)在第 15.1 章的 simple_tcp_server.go 中出現(xiàn):示例中在發(fā)生讀取錯(cuò)誤時(shí),使用 goto 來跳出無限讀取循環(huán)并關(guān)閉相應(yīng)的客戶端鏈接。
定義但未使用標(biāo)簽會(huì)導(dǎo)致編譯錯(cuò)誤:label … defined and not used
。
如果您必須使用 goto,應(yīng)當(dāng)只使用正序的標(biāo)簽(標(biāo)簽位于 goto 語句之后),但注意標(biāo)簽和 goto 語句之間不能出現(xiàn)定義新變量的語句,否則會(huì)導(dǎo)致編譯失敗。
示例 5.15 goto2.go:
// compile error goto2.go:8: goto TARGET jumps over declaration of b at goto2.go:8
package main
import "fmt"
func main() {
a := 1
goto TARGET // compile error
b := 9
TARGET:
b += a
fmt.Printf("a is %v *** b is %v", a, b)
}
問題 5.3 請(qǐng)描述下面 for 循環(huán)的輸出:
1.
i := 0
for { //since there are no checks, this is an infinite loop
if i >= 3 { break }
//break out of this for loop when this condition is met
fmt.Println("Value of i is:", i)
i++;
}
fmt.Println("A statement just after for loop.")
2.
for i := 0; i<7 ; i++ {
if i%2 == 0 { continue }
fmt.Println("Odd:", i)
}