跳至主要内容

[Golang] 流程控制 Control Flow

For Loop

基本使用

最基本的 for 迴圈會包含三個部分:

  • 起始句(init statement):可省略,在第一次疊代前會執行
  • 條件式(condition expression):在下次執行疊代中的程式碼前會評估
  • post statement:可省略,在每次執行完疊代中的程式碼後會執行
for i := 0; i < 10; i++ {
fmt.Println(i)
}

while

主要把 for 的 init statement 和 post statement 省略後,就會變成 while 語句:

// init statement 和 post statement 可以省略,就會變成 while 語句
func main() {
i := 0
for i < 10 {
fmt.Println(i)
i++
}
}

infinite loop

把 for 後面所有參數都移除,就變成 infinite loop:

for {
fmt.Println("Don't do this")
}

If

基本使用

func main() {
i := 10
if i < 5 {
fmt.Println(i, "is smaller than 5")
} else if i > 15 {
fmt.Println(i, "is equal and larger than 15")
} else {
fmt.Println(i, "is between 5 and 15")
}
}

搭配 statement 使用

iffor 類似,都可以在最前面加上 statement,它會在 if 中的程式執行前被執行;若在 statement 中宣告變數,則這個變數只能在 if 的 block 中被使用(包含 else):

// if <statement>; <condition> {...}
if i := 3; i < 5 {
fmt.Println(i, "is smaller than 5")
} else {
fmt.Println(i, "is equal or larger than 5")
}

continue and break

func main() {
brands := []string{"Apple", "Samsung", "LG", "Xiaomi", "Sony", "Nokia"}
for i, brand := range brands {
if i == 3 {
fmt.Println("Skip the brand", brand)
continue
}
if i > 3 {
fmt.Println("Break after the brand", brand)
break
}
fmt.Printf("The value at position %v is %v.\n", i, brand)
}
}

// The value at position 0 is Apple.
// The value at position 1 is Samsung.
// The value at position 2 is LG.
// Skip the brand Xiaomi
// Break after the brand Sony

switch

  • 在 Go 的 switch 中不需要使用 break(Go 執行時會自動 break)
  • switchif, for 類似,在最前面都可以加上 statement
  • 從上往下開始判斷每一個 case,並在配對到的 case 後終止

基本使用

func main() {
fmt.Print("Go runs on ")

// 等同於
// os := runtime.GOOS
// switch os {
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
fmt.Printf("%s.\n", os)
}
}

case 後面可以是 express

case 後面不一定一定要是字串,是可以放 express 的:

func main() {
num := 1
switch start := 0; num {
case start:
fmt.Println("0")
case start + 1:
fmt.Println("1")
default:
fmt.Println("other")
}
}

switch 後可以不帶變數(可用來簡化 if ... else)

switch 可以不帶變數,直接變成 if...elseif...else 的簡化版:

func main() {
currentHour := time.Now().Hour()
switch {
case currentHour < 12:
fmt.Println("Good morning!")
case currentHour < 17:
fmt.Println("Good afternoon.")
default:
fmt.Println("Good eventing")
}
}

判斷 interface 被 implement 的型別

建立 interface 後可以使用 interface.(type) 來判斷該 interface 被 implement 的型別:

var (
i interface{}
)

func convert(i interface{}) {
switch t := i.(type) {
case int:
fmt.Printf("%v is integer(%T)\n", t, t)
case string:
fmt.Printf("%v is string(%T)\n", t, t)
case float64:
fmt.Printf("%v is float64(%T)\n", t, t)
default:
fmt.Printf("type not found")
}
}

func main() {
convert(100) // 100 is integer(int)

convert(45.55) // 45.55 is float64(float64)

convert("foo") // foo is string(string)

convert(float32(10.0)) // type not found
}

Iterate

keywords: range
cardValues := []string{"Ace", "Two", "Three", "Four"}

// 如果只需要 index,可以簡寫成:
// for i := range cardValues { ... }
for i, value := range cardValues {
fmt.Println(i, value)
}

參考