Go基礎系列:流程式控制制結構

來源:互聯網
上載者:User

標籤:局限   go基礎   函數   簡寫   無限   退出   and   cond   選擇   

條件判斷結構:if else
分支選擇結構:switch case
迴圈結構:for
break:退出for或switch結構(以及select)
continue:進入下一次for迭代

雖然Go是類C的語言,但Go在這些流程式控制制語句中的條件運算式部分不使用括弧。甚至有些時候使用括弧會報錯,但有些複雜的條件判斷需要使用括弧改變優先順序。

如:

if (name == "longshuai" && age > 23) || (name == "xiaofang" && age < 22) {    print("yeyeye!!!")}
if語句
if condition1 {    // do something} else if condition2 {    // do something else} else {    // catch-all or default}

注意,Go對文法要求很嚴格。左大括弧{必須和if、else或else if在同一行,右大括弧}必須換行,如果有else或else if,則必須緊跟這兩個關鍵字。也就是說,上面的代碼結構中,大括弧的使用位置是強制規範的,不能隨意換行放置。

在Go中,if語句的condition前面可以加上初始化語句,例如Go中很常見的:

if val := 10; val > max {    // do something}

它在一定程度上等價於:

val := 10if val > max {    // do something}

但注意,前面簡寫的方式中,val的範圍只在if範圍內,if外面無法訪問這個val。如果在if語句之前已經定義了一個val,那麼這個val將被if中的val掩蓋,直到if退出後才恢複。

func main() {    val := 20    if val := 10; val > 3 {        println("true")    }    println(val)    // 輸出20}

一種解決方式是if中的初始化語句不要使用:=,而是直接使用=,但這樣會修改原始的值。

func main() {    val := 20    if val = 10; val > 3 {        println("true")    }    println(val)    // 輸出10}

在Go中,經常使用兩個(或多個)傳回值的函數,一個傳回值作為值,另一個作為布爾類型的判斷值,或者作為錯誤資訊。通常會使用if語句去檢測多個傳回值的函數是否成功。

但注意,一般有兩種判斷傳回值:一種是ok類型,一種是err類型的錯誤資訊。前者是布爾值,後者是表明錯誤資訊的字串,如果沒錯誤,則err為nil。

value,ok := func_name()if !ok {    // func_name執行錯誤    os.Exit(1)}value,err := func_name()if err != nil {    // func_name執行錯誤    os.Exit(1)    // 或 return err}

將上面的簡寫一下,得到更常見的判斷方式:

if value,ok := func_name();ok {    // ok為true,函數執行成功} else {    // ok為false,函數執行失敗    os.Exit(1)}if value,err := func_name();err != nil {    // err不為nil,說明出現錯誤    return err    //或os.Exit(1)} else {    // err為空白,說明執行正確}
switch語句

switch語句用於提供分支測試。有兩種swithc結構:expression switch和type switch,本文暫時只介紹expression switch,它用於判斷運算式是否為true。

對於expression switch,也有三種形式:等值比較、運算式比較、初始設定式。

等值比較結構:當var1的值為val1時,執行statement1,當var1的值為val2時,執行statement2,都不滿足時,執行預設的語句statement。

switch var1 {    case val1:        statement1    case val2:        statement2    default:        statement}

等值比較局限性很大,只能將var1和case中的值比較是否相等。如果想比較不等,或者其它運算式類型,可以使用下面的運算式比較結構。

運算式比較結構:評估每個case結構中的condition,只要評估為真就執行,然後退出(預設情況下)。

switch {    case condition1:        statement1    case condition2:        statement2    default:        statement}

初始設定式:可以和if一樣為switch加上初始設定式,同樣範圍只在switch可見。但注意,initialization後面記得加上分號";"結尾。見下文樣本。

switch initialization; {  // 不要省略分號    case condition1:        statement1    case condition2:        statement2    defautl:        statement}

default是可選的,且可以寫在switch的任何位置。

如果case中有多個要執行的語句,可以加大括弧,也可以不加大括弧。當只有一個語句的時候,statement可以和case在同一行。

case中可以提供多個用於測試的值,使用逗號分隔,只要有一個符合,就滿足條件:

switch var1 {    case val1,val2,val3:        statement1    case val4,val5:         statement2    default:        statement}

例如:

val := 20switch val {case 10, 11, 15:    println(11, 15)case 16, 20, 22:      // 命中    println(16, 20, 22)default:    println("nothing")}

即使是運算式比較結構,也一樣可以使用逗號分隔多個運算式,這時和使用邏輯或"||"是等價的:

func main() {    val := 21    switch {    case val % 4 == 0:        println(0)    case val % 4 == 1, val % 4 == 2:  //命中        println(1, 2)    default:        println("3")    }}

預設情況下case命中就結束,所以所有的case中只有一個會被執行。但如果想要執行多個,可以在執行完的某個case的最後一個語句上加上fallthrough,它會無條件地直接跳轉到下一條case並執行,如果下一條case中還有fallthrough,則相同的邏輯。此外,fallthrough的後面必須只能是下一個case或default,不能是額外的任何語句,否則會報錯。

例如:

func main() {    val := 21    switch val % 4 {    case 0:        println(0)    case 1, 2:         // 命中        println(1, 2)  // 輸出        fallthrough    // 執行下一條,無需條件評估        // println("sd") //不能加此行語句    case 3:        println(3)     // 輸出        fallthrough    // 執行下一條,無需條件評估    default:        println("end")  // 輸出    }}

執行結果為:

1 23end

fallthrough一般用於跳過某個case。例如:

swtich i {    case 0: fallthrough    case 1: statement1    default: statement}

它表示等於0或等於1的時候都執行statement1。這和前面case中多個評估值的功能是一樣的。

以下是一個初始設定式結構的switch樣本:

func main() {    val := 21    switch val := 23; {    case val % 4 == 0:        println(0,val)    case val % 4 == 1 || val % 4 == 2:        println(1, 2,val)    default:             // 命中        println(3,val)   // 輸出"3 23"    }    println(val)         // 輸出21}
for語句

Go中只有一種迴圈結構:for。

普通格式的for
// 完整格式的forfor init; condition; modif { }// 只有條件判斷的for,實現while的功能// 要在迴圈體中加上允出準則,否則無限迴圈for condition { }

例如:

// 完整格式func main() {    for i := 0; i < 5; i++ {        fmt.Println(i)    }}// 只有條件的格式func main() {    var i int = 5    for i >= 0 {        i = i - 1        fmt.Printf(i)    }}
無限迴圈

好幾種方式實現for的無限迴圈。只要省略for的條件判斷部分就可以實現無限迴圈。

for i := 0;;i++ for { } for ;; { }for true { }

無限迴圈時,一般在迴圈體中加上退出語句,如break、os.Exit、return等。

for range遍曆

range關鍵字非常好用,可以用來迭代那些可迭代的對象。比如slice、map、array,還可以迭代字串,甚至是Unicode的字串。

for index,value := range XXX {}

但千萬注意,value是從XXX中拷貝的副本,所以通過value去修改XXX中的值是無效的,在迴圈體中應該總是讓value作為一個唯讀變數。如果想要修改XXX中的值,應該通過index索引到源值去修改(不同類型修改的方式不一樣)。

以迭代字串為例。

func main() {    var a = "Xiaofang,你好"    for index,value := range a {        println(index,string(value))    }}

輸出結果:

0 X1 i2 a3 o4 f5 a6 n7 g8 ,9 你12 好

可見,在迭代字串的時候,是按照字元而非位元組進行索引的。

下面通過value去修改slice將無效。

func main() {    s1 := []int{11,22,33}    for index,value := range s1 {        value += 1      // 只在for結構中有效        fmt.Println(index,value)    }    fmt.Println(s1)   // for外面的結果仍然是[11 22 33]}

要在迴圈結構中修改slice,應該通過index索引的方式:

func main() {    s1 := []int{11,22,33}    for index,value := range s1 {        value += 1        s1[index] = value        fmt.Println(index,value)    }    fmt.Println(s1)   // [12 23 34]}
break和continue

breake用於退出當前整個迴圈。如果是嵌套的迴圈,則退出它所在的那一層迴圈。break除了可以用在for迴圈中,還可以用在switch結構或select結構。

continue用於退出當前迭代,進入下一輪迭代。continue只能用於for迴圈中。

標籤和goto

當某一行中第一個單詞後面跟一個冒號的時候,Go就認為這是一個標籤。例如:

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)        }    }}

使用標籤能讓break、continue以及goto跳轉到指定的位置繼續往下執行。例如這裡的continue LABEL1,當j == 4的時候,就直接跳到外層迴圈進入下一輪迭代。而break LABEL則指定直接退出LABEL所在的那一層迴圈。

goto懶得介紹了,反正沒人用,也強烈不建議使用,甚至標籤都建議不要使用。一般能使用LABEL或goto的結構,都能改寫成其它更好的語句。

Go基礎系列:流程式控制制結構

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.