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 在默認情況下,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é)作與搶占。本文將通過一些示例為大家詳細講講調(diào)度器中協(xié)作與搶占的相關(guān)知識,需要的可以參考一下2023-04-04GoLang jwt無感刷新與SSO單點登錄限制解除方法詳解
這篇文章主要介紹了GoLang jwt無感刷新與SSO單點登錄限制解除方法,JWT是一個簽名的JSON對象,通常用作Oauth2的Bearer token,JWT包括三個用.分割的部分。本文將利用JWT進行認證和加密,感興趣的可以了解一下2023-03-03Golang 統(tǒng)計字符串字數(shù)的方法示例
本篇文章主要介紹了Golang 統(tǒng)計字符串字數(shù)的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05