Go 語言入門基礎學習筆記之 Go 語言的條件語句
條件語句#
if 語句#
if 布爾表達式 {
/* 在布爾表達式為 true 時執行 */
}
if else 語句#
if 布爾表達式 {
/* 在布爾表達式為 true 時執行 */
} else {
/* 在布爾表達式為 false 時執行 */
}
if 嵌套語句#
if 布爾表達式 1 {
/* 在布爾表達式 1 為 true 時執行 */
if 布爾表達式 2 {
/* 在布爾表達式 2 為 true 時執行 */
}
}
switch 語句#
需要注意的是,switch 語句執行的過程從上至下,直到找到匹配項,匹配項後面也不需要再加 break。
switch var1 {
case val1:
...
case val2:
...
default:
...
}
switch 默認情況下 case 最後自帶 break 語句,匹配成功後就不會執行其他 case,如果我們需要執行後面的 case,可以使用 fallthrough。
使用 fallthrough 會強制執行後面的 case 語句,fallthrough 不會判斷下一條 case 的表達式結果是否為 true。
package main
import "fmt"
func main() {
switch {
case false:
fmt.Println("1、case 條件語句為 false")
fallthrough
case true:
fmt.Println("2、case 條件語句為 true")
fallthrough
case false:
fmt.Println("3、case 條件語句為 false")
fallthrough
case true:
fmt.Println("4、case 條件語句為 true")
case false:
fmt.Println("5、case 條件語句為 false")
fallthrough
default:
fmt.Println("6、默認 case")
}
}
// 輸出結果
2、case 條件語句為 true
3、case 條件語句為 false
4、case 條件語句為 true
switch 語句還可以被用於 Type-Switch 來判斷某個 interface 變量中實際存儲的變量類型。
switch x.(type){
case type:
statement(s);
case type:
statement(s);
/* 你可以定義任意個數的case */
default: /* 可選 */
statement(s);
}
比如:
package main
import "fmt"
func main() {
var x interface{}
switch i := x.(type) {
case nil:
fmt.Printf(" x 的類型 :%T",i)
case int:
fmt.Printf("x 是 int 型")
case float64:
fmt.Printf("x 是 float64 型")
case func(int) float64:
fmt.Printf("x 是 func(int) 型")
case bool, string:
fmt.Printf("x 是 bool 或 string 型" )
default:
fmt.Printf("未知型")
}
}
// 輸出結果
x 的類型 :<nil>
%T
用於輸出一個變量的數據類型
select 語句#
select 是 Go 中的一個控制結構,類似於 switch 語句。
select 語句只能用於通道操作,每個 case 必須是一個通道操作,要麼是發送要麼是接收。
select 語句會監聽所有指定的通道上的操作,一旦其中一個通道準備好就會執行相應的代碼塊。
如果多個通道都準備好,那麼 select 語句會隨機選擇一個通道執行。如果所有通道都沒有準備好,那麼執行 default 塊中的代碼。
select {
case <- channel1:
// 執行的代碼
case value := <- channel2:
// 執行的代碼
case channel3 <- value:
// 執行的代碼
// 你可以定義任意數量的 case
default:
// 所有通道都沒有準備好,執行的代碼
}
以下描述了 select 語句的語法:
- 每個 case 都必須是一個通道
- 所有 channel 表達式都會被求值
- 所有被發送的表達式都會被求值
- 如果任意某個通道可以進行,它就執行,其他被忽略。
- 如果有多個 case 都可以運行,select 會隨機公平地選出一個執行,其他不會執行。否則:
- 如果有 default 子句,則執行該語句。
- 如果沒有 default 子句,select 將阻塞,直到某個通道可以運行;Go 不會重新對 channel 或值進行求值。
package main
import (
"fmt"
"time"
)
func main() {
c1 := make(chan string)
c2 := make(chan string)
go func() {
time.Sleep(1 * time.Second)
c1 <- "one"
}()
go func() {
time.Sleep(2 * time.Second)
c2 <- "two"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
}
}
}
// 輸出結果
received one
received two
以上實例中,我們創建了兩個通道 c 1 和 c 2。
select 語句等待兩個通道的數據。如果接收到 c 1 的數據,就會打印 received one
;如果接收到 c 2 的數據,就會打印 received two
。
以下實例中,我們定義了兩個通道,並啟動了兩個協程(Goroutine)從這兩個通道中獲取數據。在 main 函數中,我們使用 select 語句在這兩個通道中進行非阻塞的選擇,如果兩個通道都沒有可用的數據,就執行 default 子句中的語句。
以下實例執行後會不斷地從兩個通道中獲取到的數據,當兩個通道都沒有可用的數據時,會輸出 no message received
。
package main
import "fmt"
func main() {
// 定義兩個通道
ch1 := make(chan string)
ch2 := make(chan string)
// 啟動兩個 goroutine,分別從兩個通道中獲取數據
go func() {
for {
ch1 <- "from 1"
}
}()
go func() {
for {
ch2 <- "from 2"
}
}()
// 使用 select 語句非阻塞地從兩個通道中獲取數據
for {
select {
case msg1 := <-ch1:
fmt.Println(msg1)
case msg2 := <-ch2:
fmt.Println(msg2)
default:
// 如果兩個通道都沒有可用的數據,則執行這裡的語句
fmt.Println("no message received")
}
}
}
Go 中沒有三目運算符,不支持
? :
形式的條件判斷