A tour of Go (2) - Go語言運算子&流程控制
Thursday, December 17, 2020
A tour of Go (2) - Go語言運算子&流程控制
1. Go語言運算子
不需要匯入包
- 算數運算子:
+
,-
,*
,/
,%
,++
,--
- 關係運算符:
==
,!=
,>
,<
,>=
,<=
- 邏輯運算子:
&&
,||
,!
- 位運算子:
&
相與,|
相或,^
異或,<<
左移n位(乘以2的n次方),>>
右移n位 - 賦值運算子:
=
,+=
,-=
,*=
,/=
,%=
,<<=
,>>=
,&=
,^=
,|=
- 其他運算子:
&
返回變數儲存地址,*
指標變數
func main() {
var a int = 4
var ptr *int // 宣告指標變數
ptr = &a // 將變數地址賦值給指標變數
println("a的值為", a); // 4
println("*ptr為", *ptr); // 4,*指標變數 -> 取得地址對應的變數值
println("ptr為", ptr); // 824633794744 直接取得變數儲存地址
}
2. 流程控制語句 —— for 迴圈
Go 只有一種迴圈結構:for
迴圈。
基本的 for
- 初始化語句:在第一次迭代前執行 e.g.,
i := 0
- 條件表示式:在每次迭代前求值 e.g.,
i < 10
- 後置語句:在每次迭代的結尾執行 e.g.,
i++
for i := 0; i < 10; i++ {
sum += i
}
初始化語句通常為一句短變數宣告,該變數宣告僅在 for
語句的作用域中可見
注意:和其他語言不同,Go 的 for
語句後面的三個構成部分外沒有小括號, 大括號 { }
則是必須的。
初始化語句和後置語句是可選的,而條件表示式必須宣告。
sum := 1 for ; sum < 1000; { sum += sum }
此時你可以去掉分號,因為 C 的 while
在 Go 中叫做 for
。
sum := 1
for sum < 1000 { // 此時等價於C語言中的while
sum += sum
}
如果省略迴圈條件,就會變成無限迴圈。
3. 流程控制語句 —— if 條件
Go 的 if
語句與 for
迴圈類似,表示式外無需小括號 ( )
,而大括號 { }
則是必須的。
if x < 0 {
return x
}
同 for
一樣, if
語句可以在條件表示式前執行一個簡單的語句。
該語句宣告的變數作用域僅在 if
之內。
if v := math.Pow(x, n); v < lim { // 可以在條件表示前執行一個語句,如變數短賦值
return v
}
在 if
的簡短語句中宣告的變數同樣可以在任何對應的 else
塊中使用。
4. 流程控制語句 —— switch 條件
switch
是編寫一連串 if - else
語句的簡便方法。它會執行第一個值等於條件表示式的 case
語句。
Go 只執行選定的 case
,而非之後所有的 case
。 實際上,Go 自動提供了在這些語言中每個 case
後面所需的 break
語句。
如果執行的 case
帶有 fallthrough
,程式會繼續執行下一條 case
,且它不會去判斷下一個 case
的表示式是否為 true
。直到遇見不帶 fallthrough
的 case
或執行完全部 case
和 default
,程式停止。
Go 的另一點重要的不同在於 switch
的 case
無需為常量,且取值不必為整數。
沒有條件的 switch
同 switch true
一樣。這種形式能將一長串的 if-then-else 寫得更加清晰。
t := time.Now() // 將不同的判斷條件寫在 case 條件處,代替一長串的 if-then-else
switch {
case t.Hour() < 12:
fmt.Println("Good morning!")
case t.Hour() < 17:
fmt.Println("Good afternoon.")
default:
fmt.Println("Good evening.")
}
5. 流程控制語句 —— defer 推遲執行
defer
語句會將函式推遲到外層函式返回之後執行。
推遲呼叫的函式其引數會立即求值,但直到外層函式返回前該函式都不會被呼叫。
func main() {
defer fmt.Println("world")
fmt.Println("hello")
}
推遲的函式呼叫會被壓入一個棧中。當外層函式返回時,被推遲的函式會按照後進先出的順序呼叫。
func main() { // 結果:counting, done, 9, 8, ..., 0
fmt.Println("counting")
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
fmt.Println("done")
}