帶你學夠浪:Go語言基礎系列 - 8分鐘學控制流語句

檸檬橙1024發表於2020-06-07

文章每週持續更新,原創不易,「三連」讓更多人看到是對我最大的肯定。可以微信搜尋公眾號「 後端技術學堂 」第一時間閱讀(一般比部落格早更新一到兩篇)

對於一般的語言使用者來說 ,20% 的語言特性就能夠滿足 80% 的使用需求,剩下在使用中掌握。基於這一理論,Go 基礎系列的文章不會刻意追求面面俱到,但該有知識點都會覆蓋,目的是帶你快跑趕上 Golang 這趟新車。

Hurry up , Let's go !

控制語句是程式的靈魂,有了它們程式才能完成各種邏輯,今天我們就來學習 Go 中的各種控制語句。

通過本文的學習你將掌握以下知識:

  • if 條件語句
  • for 迴圈語句
  • switch 語句
  • defer 延遲呼叫

if 條件語句

與大多數程式語言一樣,if 用於條件判斷,當條件表示式 exprtrue 執行 {} 包裹的訊息體語句,否則不執行。

語法是這樣的:

if expr {
    // some code
}

**注意:**語法上和 c 語言不同的是不用在條件表示式 expr 外帶括號,和 python 的語法類似。

當然,如果想在條件不滿足的時候做點啥,就可以 if 後帶 else 語句。語法:

if expr {
    // some code
} else {
    // another code
}

不僅僅是 if

除了可以在 if 中做條件判斷之外,在 Golang 中你甚至可以在 if 的條件表示式前執行一個簡單的語句。

舉個例子:

if x2 := 1; x2 > 10 { 
    fmt.Println("x2 great than 10")
} else {
    fmt.Println("x2 less than 10", x2)
}

上面的例子在 if 語句中先宣告並賦值了 x2,之後對 x2 做條件判斷。

注意:此處在 if 內宣告的變數 x2 作用域僅限於 if 和else 語句。

for迴圈語句

當需要重複執行的時候需要用到迴圈語句,Go 中只有 for 這一種迴圈語句。

標準的for迴圈語法:

for 初始化語句; 條件表示式; 後置語句 {
    // some code
}

這種語法形式和 C 語言中 for 迴圈寫法還是很像的,不同的是不用把這三個部分用 () 括起來。迴圈執行邏輯:

  • 初始化語句:初始迴圈時執行一次,做一些初始化工作,一般是迴圈變數的宣告和賦值。
  • 條件表示式:在每次迴圈前對條件表示式求值操作,若求值結果是 true 則執行迴圈體內語句,否則不執行。
  • 後置語句:在每次迴圈的結尾執行,一般是做迴圈變數的自增操作。

舉個例子:

sum := 0
for i := 0; i < 10; i++ {
    sum += i // i作用域只在for語句內
    fmt.Println(i, sum)
}

注意:迴圈變數i 的作用域只在 for 語句內,超出這個範圍就不能使用了。

while迴圈怎麼寫?

前面說了,Golang 中只有 for 這一種迴圈語法,那有沒有類似 C 語言中 while 迴圈的寫法呢?答案是有的:把 for 語句的前後兩部分省略,只留中間的「條件表示式」的 for 語句等價於 while 迴圈。

像下面這樣:

sum1 := 0
for ;sum1 < 10; { // 可以省略初始化語句和後置語句
    sum1++
    fmt.Println(sum1)
}

上面的示例沒有初始化語句和後置語句,會迴圈執行 10 次後退出。

當然你要是覺得前後的分號也不想寫了,也可以省略不寫,上面的程式碼和下面是等效的:

sum1 := 0
for sum1 < 10 { // 可以省略初始化語句和後置語句,分號也能省略
    sum1++
    fmt.Println(sum1)
}

在 Golang 中死迴圈可以這樣寫,相當於 C 語言中的 while(true)

 for { // 死迴圈
  // your code
 }

switch 語句

switch 語句可以簡化多個 if-else 條件判斷寫法,避免程式碼看起來雜亂。

可以先定義變數,然後在 switch 中使用這個變數。

 a := 1
 switch a {
 case 1: 
  fmt.Println("case 1") // 不用寫break 執行到這自動跳出
 case 2:
  fmt.Println("case 2")
 default:
  fmt.Printf("unexpect case")
 }
輸出:case 1

從 C 語言過來的朋友一定有這樣的經歷:經常會在 case 語句中漏掉 break 導致程式繼續往下執行,從而產生奇奇怪怪的 bug ,這種問題在 Golang 中不復存在了。

Golang 在每個 case 後面隱式提供 break 語句。 除非以 fallthrough 語句結束,否則分支會自動終止。

 switch a := 1; a { //這裡有分號
 case 1: // case 無需為常量,且取值不必為整數。
  fmt.Println("case 1") // 不用寫break 執行到自動跳出 除非以 fallthrough 語句結束
  fallthrough
 case 2:
  fmt.Println("case 2")
 default:
  fmt.Printf("unexpect case")
 }
輸出:
case 1
case 2

還可以直接在 switch 中定義變數後使用,但是要注意變數定義之後又分號,比如下面這樣:

 switch b :=1; b { //注意這裡有分號
 case 1: 
  fmt.Println("case 1") 
 case 2:
  fmt.Println("case 2")
 default:
  fmt.Printf("unexpect case")
 }

沒有條件的switch

沒有條件的 switch 同 switch true 一樣,只有當 case 中的表示式值為「真」時才執行,這種形式能簡化複雜的 if-else-if else 語法。

下面是用 if 來寫多重條件判斷,這裡寫的比較簡單若是再多幾個 else if 程式碼結構看起來會更糟糕。

    a := 1
    if a > 0 {
        fmt.Println("case 1") 
    } else if a < 0 {
        fmt.Println("case 2")   
    } else {
        fmt.Printf("unexpect case")   
    }

如果用上不帶條件的 switch 語句,寫出來就會簡潔很多,像下面這樣。

 a := 1
 switch {    // 相當於switch true
 case a > 0: // 若表示式為「真」則執行 
  fmt.Println("case 1") 
 case a < 0:
  fmt.Println("case 2")
 default:
  fmt.Printf("unexpect case")
 }

defer 語句

defer 語句有延遲呼叫的效果。具體來說defer後面的函式呼叫會被壓入堆疊,當外層函式返回才會對壓棧的函式按後進先出順序呼叫。說起來有點抽象,舉個例子:

package main

import "fmt"

func main() {
 fmt.Println("entry main")
 for i := 0; i < 6; i++ {
  defer fmt.Println(i)
 }
 fmt.Println("exit main")
}

fmt.Println(i) 不會每次立即執行,而是在 main 函式返回之後才依次呼叫,編譯執行上述程式的輸出:

entry main
exit main  //外層函式返回
5
4
3
2
1
0

上面是簡單的使用示例,實際使用中defer 通常用來釋放函式內部變數,因為它可以在外層函式 return 之後繼續執行一些清理動作。

這在檔案類操作異常處理中非常實用,比如用於釋放檔案描述符,我們以後會講解這塊應用,總之先記住 defer 延遲呼叫的特點。

總結

通過本文的學習,我們掌握了 Golang 中基本的控制流語句,利用這些控制語句加上一節介紹的變數等基礎知識,可以構成豐富的程式邏輯,就能用 Golang 來做一些有意思的事情了。

感謝各位的閱讀,文章的目的是分享對知識的理解,技術類文章我都會反覆求證以求最大程度保證準確性,若文中出現明顯紕漏也歡迎指出,我們一起在探討中學習.

今天的技術分享就到這裡,我們下期再見。


創作不易,白票不是好習慣,如果在我這有收穫,動動手指「點贊」「關注」是對我持續創作的最大支援。

微信搜尋公眾號「 後端技術學堂 」回覆「資料」「1024」有我給你準備的各種程式設計學習資料。文章每週持續更新,我們下期見!

本文使用 mdnice 排版

相關文章