Golang通脈之流程控制詳情
前言:
流程控制是每種編程語言控制邏輯走向和執(zhí)行次序的重要部分,流程控制可以說是一門語言的“經(jīng)脈”。
Go語言中最常用的流程控制有if和for,而switch和goto主要是為了簡化代碼、降低重復(fù)代碼而生的結(jié)構(gòu),屬于擴展類的流程控制。
1、if else(分支結(jié)構(gòu))
1.1 if條件判斷基本寫法
Go語言中if條件判斷的格式如下:
if 表達式1 {
分支1
} else if 表達式2 {
分支2
} else{
分支3
}
當(dāng)表達式1的結(jié)果為true時,執(zhí)行分支1,否則判斷表達式2,如果滿足則執(zhí)行分支2,都不滿足時,則執(zhí)行分支3。 if判斷中的else if和else都是可選的,可以根據(jù)實際需要進行選擇。
關(guān)于 if 條件語句的使用有一些規(guī)則:
- if 后面的條件表達式不需要使用 (),這和有些編程語言不一樣,也更體現(xiàn) Go 語言的簡潔;
- 每個條件分支(
if或者else)中的大括號是必須的,哪怕大括號里只有一行代碼(如示例); - if 緊跟的大括號 { 不能獨占一行,
else前的大括號 } 也不能獨占一行,否則會編譯不通過; - 在
if……else條件語句中還可以增加多個else if,增加更多的條件分支。
1.2 if條件判斷特殊寫法
if條件判斷還有一種特殊的寫法,可以在 if 表達式之前添加一個執(zhí)行語句,再根據(jù)變量值進行判斷:
func main() {
if i:=6; i >10 {
fmt.Println("i>10")
} else if i>5 && i<=10 {
fmt.Println("5<i<=10")
} else {
fmt.Println("i<=5")
}
}
2、for(循環(huán)結(jié)構(gòu))
Go 語言中的所有循環(huán)類型均可以使用for關(guān)鍵字來完成。
for循環(huán)的基本格式如下:
for 初始語句;條件表達式;更新語句{
循環(huán)體語句
}
條件表達式返回true時循環(huán)體不停地進行循環(huán),直到條件表達式返回false時自動退出循環(huán)。
func forDemo() {
for i := 0; i < 10; i++ {
fmt.Println(i)
}
}
for循環(huán)的初始語句可以被忽略,但是初始語句后的分號必須要寫,例如:
func forDemo2() {
i := 0
for ; i < 10; i++ {
fmt.Println(i)
}
}
for循環(huán)的初始語句和結(jié)束語句都可以省略,例如:
func forDemo3() {
i := 0
for i < 10 {
fmt.Println(i)
i++
}
}
這種寫法類似于其他編程語言中的while,在while后添加一個條件表達式,滿足條件表達式時持續(xù)循環(huán),否則結(jié)束循環(huán)。
2.1 無限循環(huán)
for {
循環(huán)體語句
}
for循環(huán)可以通過break、goto、return、panic語句強制退出循環(huán)。
在 Go 語言中,同樣支持使用 continue、break 控制 for 循環(huán):
continue 可以跳出本次循環(huán),繼續(xù)執(zhí)行下一個循環(huán)。
break 可以跳出整個 for 循環(huán),哪怕 for 循環(huán)沒有執(zhí)行完,也會強制終止。
3、for range(鍵值循環(huán))
Go語言中可以使用for range遍歷數(shù)組、切片、字符串、map 及通道(channel)。
通過for range遍歷的返回值有以下規(guī)律:
- 數(shù)組、切片、字符串返回索引和值。
map返回鍵和值。- 通道(
channel)只返回通道內(nèi)的值。
注意:
與 for 不同的是,range 對每個迭代值都創(chuàng)建了一個拷貝。因此如果每次迭代的值內(nèi)存占用很小的情況下,for 和 range 的性能幾乎沒有差異,但是如果每個迭代值內(nèi)存占用很大,這種情況下差距就非常明顯了。
簡單的例子證明 range 迭代時,返回的是拷貝。
persons := []struct{ no int }{{no: 1}, {no: 2}, {no: 3}}
for _, s := range persons {
s.no += 10
}
for i := 0; i < len(persons); i++ {
persons[i].no += 100
}
fmt.Println(persons) // [{101} {102} {103}]
persons是一個長度為 3 的切片,每個元素是一個結(jié)構(gòu)體。- 使用
range迭代時,試圖將每個結(jié)構(gòu)體的 no 字段增加 10,但修改無效,因為range返回的是拷貝。 - 使用 for 迭代時,將每個結(jié)構(gòu)體的 no 字段增加 100,修改有效
range 在迭代過程中返回的是迭代值的拷貝,如果每次迭代的元素的內(nèi)存占用很低,那么 for 和 range 的性能幾乎是一樣,例如 []int。但是如果迭代的元素內(nèi)存占用較高,例如一個包含很多屬性的 struct 結(jié)構(gòu)體,那么 for 的性能將顯著地高于range,有時候甚至?xí)猩锨П兜男阅懿町悺τ谶@種場景,建議使用 for,如果使用 range,建議只迭代下標(biāo),通過下標(biāo)訪問迭代值,這種使用方式和 for 就沒有區(qū)別了。如果想使用 range 同時迭代下標(biāo)和值,則需要將切片/數(shù)組的元素改為指針,才能不影響性能。
4、switch case
使用switch語句可方便地對大量的值進行條件判斷。
func switchDemo1() {
finger := 3
switch finger {
case 1:
fmt.Println("大拇指")
case 2:
fmt.Println("食指")
case 3:
fmt.Println("中指")
case 4:
fmt.Println("無名指")
case 5:
fmt.Println("小拇指")
default:
fmt.Println("無效的輸入!")
}
}
Go語言規(guī)定每個switch只能有一個default分支。
一個分支可以有多個值,多個case值中間使用英文逗號分隔。
func testSwitch3() {
switch n := 7; n {
case 1, 3, 5, 7, 9:
fmt.Println("奇數(shù)")
case 2, 4, 6, 8:
fmt.Println("偶數(shù)")
default:
fmt.Println(n)
}
}
分支還可以使用表達式,這時候switch語句后面不需要再跟判斷變量:
func switchDemo4() {
age := 30
switch {
case age < 25:
fmt.Println("好好學(xué)習(xí)吧")
case age > 25 && age < 35:
fmt.Println("好好工作吧")
case age > 60:
fmt.Println("好好享受吧")
default:
fmt.Println("活著真好")
}
}
在 Go 語言中,switch 的 case 從上到下逐一進行判斷,一旦滿足條件,立即執(zhí)行對應(yīng)的分支并返回,其余分支不再做判斷。也就是說 Go 語言的 switch 在默認(rèn)情況下,case 最后自帶 break。這和其他編程語言不一樣,比如 C 語言在 case 分支里必須要有明確的 break 才能退出一個 case。Go 語言的這種設(shè)計就是為了防止忘記寫 break 時,下一個 case 被執(zhí)行。
fallthrough語法可以執(zhí)行滿足條件的case的下一個case,是為了兼容C語言中的case設(shè)計的。
func switchDemo5() {
s := "a"
switch {
case s == "a":
fmt.Println("a")
fallthrough
case s == "b":
fmt.Println("b")
case s == "c":
fmt.Println("c")
default:
fmt.Println("...")
}
}
輸出:
a
b
5、goto(跳轉(zhuǎn)到指定標(biāo)簽)
goto語句通過標(biāo)簽進行代碼間的無條件跳轉(zhuǎn)。goto語句可以在快速跳出循環(huán)、避免重復(fù)退出上有一定的幫助。Go語言中使用goto語句能簡化一些代碼的實現(xiàn)過程。
例如雙層嵌套的for循環(huán)要退出時:
func gotoDemo1() {
var breakFlag bool
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j == 2 {
// 設(shè)置退出標(biāo)簽
breakFlag = true
break
}
fmt.Printf("%v-%v\n", i, j)
}
// 外層for循環(huán)判斷
if breakFlag {
break
}
}
}
使用goto語句能簡化代碼:
func gotoDemo2() {
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j == 2 {
// 設(shè)置退出標(biāo)簽
goto breakTag
}
fmt.Printf("%v-%v\n", i, j)
}
}
return
// 標(biāo)簽
breakTag:
fmt.Println("結(jié)束for循環(huán)")
}
6、break(跳出循環(huán))
break語句可以結(jié)束for、switch和select的代碼塊。
break語句還可以在語句后面添加標(biāo)簽,表示退出某個標(biāo)簽對應(yīng)的代碼塊,標(biāo)簽要求必須定義在對應(yīng)的for、switch和 select的代碼塊上。 舉個例子:
func breakDemo1() {
BREAKDEMO1:
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j == 2 {
break BREAKDEMO1
}
fmt.Printf("%v-%v\n", i, j)
}
}
fmt.Println("...")
}
7、continue(繼續(xù)下次循環(huán))
continue語句可以結(jié)束當(dāng)前循環(huán),開始下一次的循環(huán)迭代過程,僅限在for循環(huán)內(nèi)使用。
在 continue語句后添加標(biāo)簽時,表示開始標(biāo)簽對應(yīng)的循環(huán)。例如:
func continueDemo() {
forloop1:
for i := 0; i < 5; i++ {
// forloop2:
for j := 0; j < 5; j++ {
if i == 2 && j == 2 {
continue forloop1
}
fmt.Printf("%v-%v\n", i, j)
}
}
}
到此這篇關(guān)于Golang通脈之流程控制詳情的文章就介紹到這了,更多相關(guān)Golang通脈之流程控制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go調(diào)度器學(xué)習(xí)之協(xié)作與搶占詳解
如果某個G執(zhí)行時間過長,其他的G如何才能被正常調(diào)度,這就引出了接下來的話題:協(xié)作與搶占。本文將通過一些示例為大家詳細(xì)講講調(diào)度器中協(xié)作與搶占的相關(guān)知識,需要的可以參考一下2023-04-04
GoLang jwt無感刷新與SSO單點登錄限制解除方法詳解
這篇文章主要介紹了GoLang jwt無感刷新與SSO單點登錄限制解除方法,JWT是一個簽名的JSON對象,通常用作Oauth2的Bearer token,JWT包括三個用.分割的部分。本文將利用JWT進行認(rèn)證和加密,感興趣的可以了解一下2023-03-03
Golang 統(tǒng)計字符串字?jǐn)?shù)的方法示例
本篇文章主要介紹了Golang 統(tǒng)計字符串字?jǐn)?shù)的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05
Go語言標(biāo)準(zhǔn)輸入輸出庫的基本使用教程
輸入輸出在任何一門語言中都必須提供的一個功能,下面這篇文章主要給大家介紹了關(guān)于Go語言標(biāo)準(zhǔn)輸入輸出庫的基本使用,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-02-02

