天天看點

【Go語言】【9】GO語言的循環語句

一、循環語句

    循環語句即for語句,您可能說:“不對,它不僅僅是for語句,還有while或者do-while”,真的很遺憾,GO語言真的隻有for,它認為提供一種就可以了,提供多了怕給程式員帶來麻煩 :)

下面我們使用for循環計算1+2+3+4+……+100的和,和其它語言一樣,我們使用循環100次的辦法:

定義一個變量,讓它從1開始循環100次,每次都判斷它是否小于101,若是變量就加1

代碼如下:

// 聲明變量sum并初始化為0

sum := 0

// 定義變量i,循環100次,每次判斷是否小于101

for i:= 1; i< 101; i++{

   // 累加總和

   sum += i

}

// 列印結果

fmt.Println("sum=", sum)

結果如下圖:

【Go語言】【9】GO語言的循環語句

1、習慣的養成

若您一直使用C/C++/Java開發的話,此時您可能會說:“for循環與if一樣,後面沒有括号,真不習慣”,是的,一開始真不習慣,等您寫上30遍之後就習慣了

【Go語言】【9】GO語言的循環語句

2、上例變形

有的語言不允許在for後面定義變量,那麼上例就可以變形為

sum, i := 0, 1

for i < 101 {

    sum += i

    i++

把for後面的變量i定義移至for的上面,i自增加放到for循環體内部,for後面隻用于條件判斷

3、無限循環

既然GO語言去除了while關鍵字,哪麼怎麼表達無限循環呢?秘密就是for後面什麼表達式都不帶

for {

    if i > 100 {

        break

    }

既然for後面無任何條件表達式了,但總不能讓CPU一直跑下去構成死循環吧,是以這裡使用了break關鍵字,當條件滿足時break可以從目前for循環跳出來

二、range周遊

對于一篇部落格文章來說,它有ID(blogId)、标題(blogTitle)、内容(blogContent)、發表日期(blogDate)等組成,假如這些資訊都放在一個字元串數組中:

blog := []string{"blogId", "blogTitle", "blogContent", "blogDate"}

那麼我們怎麼周遊這個數組呢?使用循環語句是我們最常用,同時也是最先想到的:

for i := 0; i < len(blog); i++ {

    fmt.Printf("%s\t", blog[i])

若讀者對JavaScript腳本熟悉的話,應該知道有一個each周遊用法:

$.each(blog, function(i, item){

    /* 這裡的i為blog數組的索引,item為blog數組索引對應的值,例如當i值為1時,item的值為blogTitle */

    alert("i = " + i + ", value = " + item)

});

用戶端腳本的程式員是非常鐘愛這個周遊用法的,所幸GO語言也提供了類似用法:range,它和for關鍵字一塊用于對數組、切片、字元串和map周遊。現在使用range把上面的周遊重寫一下:

for i, value := range blog {

   fmt.Println("索引", i, "對應的值為", value)

運作結果:

【Go語言】【9】GO語言的循環語句

管中窺豹,可見一斑,GO語言将很多語言的優點内置到自身裡面,這也是為何在《【3】GO語言常量》中說到:“剛開始接觸GO,感覺它就是一個大雜燴,有很多語言的影子”的原因 :)

三、跳轉語句

    使用循環時常伴随着break、continue、goto關鍵字,是的,您沒有看錯,goto關鍵字在GO語言中得到了重用,早些年剛接觸程式設計時,有經驗的程式員總是諄諄教導:“能不用goto的就不要用goto”,是以很多語言總是在刻意回避goto,但在惜關鍵字如金的GO語言中,goto又熠熠生輝起來。

下面使用goto關鍵字重寫1+2+3+4+……+100的循環例子:

【Go語言】【9】GO語言的循環語句

先是定義了一個索引變量i和求和變量sum,然後定義了一個标簽MYBOWL(快到我的碗裡來

【Go語言】【9】GO語言的循環語句

),然後判斷索引變量i是否到了101,若沒有到則sum值就加i,再i++,然後再跳轉到MYBOWL;當條件不滿足之後(即i到了101)就輸出1到100的總和

【備注】:

1、GO語言沒有++i,隻有i++

還是那句話,GO語言認為一種方法能把問題解決就不用提供第二種方法了

2、标簽的作用域

上例中MYBOWL是一個标簽,它的作用域包括

if i < 101 {

    goto MYBOWL

但不包括fmt.Println("sum=",sum),否則就會輸出100次"sum="

四、練習題

1、請問該程式的輸出結果是多少?

    for i := 0; i < 5; i++ {

        if i > 3 {

            fmt.Println("i=", i)

            break

        }

答案:

死循環。由于break隻是跳出目前層的循環,是以當i=4時break可以使程式跳出for i:=0; i<5;i++{}這層循環,但跳不出第一層for{}這個無限循環。

2、請問該程式的輸出結果是多少?

MYBOWL:

    for {

        for i := 0; i < 5; i++ {

            if i > 3 {

                fmt.Println("i=", i)

break

            }

該程式與上面程式1類似,隻是增加了一個标簽MYBOWL,那麼這個程式會怎麼樣呢?

【Go語言】【9】GO語言的循環語句

我們把MYBOWL标簽及for{}無限循環看作第一層循環,for i:=0;i<5;i++{}看作第二層循環,當i為4時條件語句滿足,執行break跳出第二層循環進入第一層循環,由于第一層循環是無限循環,是以這裡是死循環,與MYBOWL标簽沒有任何關系。

3、請問該程式的輸出結果是多少?

break MYBOWL

該程式與程式2不同之外僅在于break語句

輸出i=4

原因是由于當i=4時條件語句滿足,輸出i=4後執行break語句,這裡的break後面添加了标簽MYBOWL,這也意味着是跳出MYBOWL标簽,而MYBOWL标簽是第一層循環,是以程式可以結束。

結束語:

要想熟悉一門語言,最重要的是用該語言寫應用程式,多寫就能多體會,熟能生巧 :)