iT邦幫忙

2023 iThome 鐵人賽

DAY 7
0
Modern Web

起步Go!Let's Go!系列 第 7 篇

[ Day 07 ] Go 迴圈 - for 迴圈的魅力

  • 分享至 

  • xImage
  •  

迴圈是用來重複執行一段程式碼區塊,直到某個條件滿足為止。這樣可以有效地處理重複執行的任務,而不用手動重複相同的程式碼。如下:

package main
import "fmt"
func main(){
    fmt.Println("Hello!!")
    fmt.Println("Hello!!")
    fmt.Println("Hello!!")
}

執行結果:
Hello!!
Hello!!
Hello!!

這個動作重複了,那就可以用迴圈來簡化。

在 Ruby 中有 for in loop 和 while loop 卻沒有 for loop。
但在 Go ,剛好相反,Go 只有一種迴圈,就是 for loop。
因為 Go 沒有 while 這個關鍵字,而且全都是用 for 來表示。

for 迴圈

基本語法一

for loop 迴圈的工作方式很簡單,當滿足 for loop中的條件式就會執行該迴圈內的程式,當條件式為 false 時,結束該迴圈。

for 布林值{
    若布林值為 true,執行程式區塊
    執行完後,回到迴圈的開頭再來一次
}
package main
import "fmt"
func main(){
    var x int = 0
    for x < 3 {
        fmt.Println(x)
        x++
    }
}

執行結果:
0
1
2

程式範例

以最前面的範例來看,可以這樣做:

package main
import "fmt"
func main(){
    x := 1
    for x <= 3{
        fmt.Println("Hello!!")
        x = x + 1
    }
}

執行結果:
Hello!!
Hello!!
Hello!!

其實我們也可以把 x = x + 1 改成 x++,意思是一樣的。

package main
import "fmt"
func main(){
    x := 1
    for x <= 3{
        fmt.Println("Hello!!")
        x++
    }
}

執行結果:
Hello!!
Hello!!
Hello!!

for loop 是看條件去決定要不要執行的,所以當條件不符時,也就不會執行。

package main
import "fmt"
func main(){
    x := 1
    for x > 3{
        fmt.Println("Hello!!")
        x++
    }
}

執行結果:
(甚麼鬼都沒有!!!)

小小練習

印出1~10

package main
import "fmt"
func main(){
    i := 1
    for i <= 10{
        fmt.Printf("%v,",i)
        i++
    }
}

執行結果:
1,2,3,4,5,6,7,8,9,10

基本語法二

從上面這種寫法,不難看出 for loop 一定要有個初始值,再給他一個條件,最後再給他一個遞增或遞減的指令。
除了第一種的寫法,但其實我們可以將這三件事合起來。

for 初始化命令; 布林值; 重複執行的命令{
    若布林值為 true,執行程式區塊
    執行完後,回到迴圈的開頭再來一次
}
package main
import "fmt"
func main() {
	var x int = 0
	for x = 0; x < 3; x++ {
		fmt.Println(x)
	}
}

執行結果:
0
1
2

程式範例

package main
import "fmt"
func main(){
    for x := 1; x<= 5; x++{
        fmt.Println("Hello!!")
    }
}

執行結果:
Hello!!
Hello!!
Hello!!
Hello!!
Hello!!

package main
import "fmt"
func main(){
    x := 1
    for x<= 5{
        fmt.Println("Hello!!")
        x++
    }
}

這兩種寫法幾乎相同的。

程式練習

基本練習:計算 1~50 的和:

package main
import "fmt"
func main() {
    result := 0
    for i := 1; i <= 50; i++ {
        result = result + i
    }
    fmt.Println(result)

執行結果:
1275

package main
import "fmt"
func main() {
    var result int = 0
    var i int = 1
    for i <= 50 {
        result = result + i
        i++
    }
    fmt.Println(result)

執行結果:
1275

不用給全部參數的 for

其實不用每個參數都給,但一定要給兩個;,不然 Go 是不會知道你做甚麼。

package main
import "fmt"
func main(){
    i := 1
    for ; i<= 5; i++{
        fmt.Printf("%d,", i)
    }
}

執行結果:
1,2,3,4,

也可以這樣寫:

package main
import "fmt"
func main(){
    i := 1
    for ; i<= 5; {
        fmt.Printf("%d,", i)
        i++
    }
}

執行結果:
1,2,3,4,5

以上的兩個寫法等於:

package main
import "fmt"
func main(){
    for i := 1; i <= 5; i++{
        fmt.Printf("%d,", i)
    }
}

執行結果:
1,2,3,4,5,

這三種寫法的執行結果都是一樣的。

無窮迴圈

如果不小心寫到永遠為真的參數,那程式就會永遠停不下來。

package main
import "fmt"
func main(){
    i := 1 
    for i == 1{
        fmt.Printf("%d", i)
    }
}

執行結果:
1111111111111111111111111.............(無限列車)

接著,VScode 就會崩潰。

但如果你真的需要一隻無窮迴圈的程式,那可以把 for 裡的條件設成 true 那就會不斷執行。

package main
import "fmt"
func main(){
    for true {
        fmt.Printf("Hi~")
    }
}

另外,Go 提供更簡單的寫法:

package main
import "fmt"
func main(){
    for {
        fmt.Printf("Hi")
    }
}

這樣就會是一個無窮迴圈。

變數作用範圍

在解釋什麼是變數作用範圍之前,先來看這支程式。

package main
import "fmt"
func main(){
    for i := 1; i <= 10; i++ {
        fmt.Printf("%d,", i)
    }
    fmt.Printf("%d,", i)
}

執行結果:
undefined: i (exit status 1)

當在 for 迴圈外(第 7 行)要取用 for 迴圈的變數(第 4 行)時就無法使用,這是很正常的事,許多的程式都有這個規則,在 { } 中,這稱為 scope ,所以在 scope 內宣告的變數是不能在外面使用。

要解決這個問題,可以將 i 宣告在 scope 之外:

package main
import "fmt"
func main(){
    i := 1
    for ; i <= 10; i++ {
        fmt.Printf("%d,", i)
    }
    fmt.Printf("\n%d,", i)
}

執行結果:
1,2,3,4,5,6,7,8,9,10,
11,

我們繼續延伸來看以下兩種 for loop 的寫法:

i := 1
for ; i <= 10; i ++{
    print("Hi!!")
}

以及

for i := 1; i <= 10; i ++{
    print("Hi!!")
}

乍看好像做的事情都是一樣的,得到的結果也是一樣的,到這兩者還是有微小的差異。如下:

  1. 寫法一:
package main
import "fmt"
func main(){
    i := 1
    for i <= 10{
        fmt.Printf("%d,", i)
        i ++
    }
    fmt.Printf("\n%d,", i) // i 在這裡能被存取
}
  1. 寫法二:
package main
import "fmt"
func main(){
    for i := 1; i <= 10; i++ {
        fmt.Printf("%d,", i)
    }
    fmt.Printf("\n%d,", i) // i 在這裡不能被存取
}

根據上面的兩個例子,可以看到當把 i 變數宣告在 for loop 外面時,在迴圈外也可以使用 i。
因此,如果你需要在迴圈結束後存取 i,則使用第一種寫法,如果只需要在迴圈內使用 i,則使用第二種寫法。

參考資料:

  1. Golang 流程控制 - for 迴圈基礎 By 彭彭

上一篇
[ Day 06 ] Go 流程控制 - 要不要?if 就是這個問題
下一篇
[ Day 08 ] Go 流程控制 - for 迴圈中的 break 和 continue 命令
系列文
起步Go!Let's Go! 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言