在Go語言中,select語句類似于switch語句,但是在select語句中,case語句指的是通信,即通道上的發(fā)送或接收操作。
語法:
select{
case SendOrReceive1: // 語句
case SendOrReceive2: // 語句
case SendOrReceive3: // 語句
.......
default: // 語句重要事項:
Select語句等待通信(發(fā)送或接收操作)準備就緒,以便在某些情況下開始。
package main
import (
"fmt"
"time"
)
// 函數(shù) 1
func portal1(channel1 chan string) {
time.Sleep(3 * time.Second)
channel1 <- "Welcome to channel 1"
}
// 函數(shù) 2
func portal2(channel2 chan string) {
time.Sleep(9 * time.Second)
channel2 <- "Welcome to channel 2"
}
func main() {
// 創(chuàng)建通道
R1 := make(chan string)
R2 := make(chan string)
// 使用goroutine調(diào)用函數(shù)1和函數(shù)2
go portal1(R1)
go portal2(R2)
select {
// case 1
case op1 := <-R1:
fmt.Println(op1)
// case 2
case op2 := <-R2:
fmt.Println(op2)
}
}輸出:
Welcome to channel 1
用法解釋:在上面的程序中,portal1休眠3秒,portal2休眠9秒,在它們的休眠時間結(jié)束后,它們將準備繼續(xù)進行?,F(xiàn)在,select語句等待它們的睡眠時間,當portal2醒來時,它選擇case 2并輸出"Welcome to channel 1"。如果門戶1在portal2之前喚醒,那么將輸出“Welcome to channel 2”。
如果select語句不包含任何case語句,則該select語句將永遠等待。
語法:
select{}package main
func main() {
//沒有任何case,將一直等待
select{ }
}輸出:
fatal error: all goroutines are asleep - deadlock! goroutine 1 [select (no cases)]: main.main() /home/runner/main.go:9 +0x20 exit status 2
select語句中的default語句用于保護select語句不被阻塞。當沒有case語句準備進行時,將執(zhí)行此語句。
package main
import "fmt"
func main() {
//創(chuàng)建通道
mychannel := make(chan int)
select {
case <-mychannel:
default:
fmt.Println("Not found")
}
}輸出:
Not found
select語句的阻塞意味著當尚無case語句準備就緒且select語句不包含任何default語句時,則select語句將阻塞,直到至少一個case語句或通信則可以繼續(xù)。
package main
func main() {
//創(chuàng)建通道
mychannel := make(chan int)
//通道尚未準備好
//并且沒有默認語句
select {
case <-mychannel:
}
}輸出:
fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan receive]: main.main() /home/runner/main.go:14 +0x52 exit status 2
在select語句中,如果準備好處理多種情況,則可以隨機選擇其中一種。
package main
import "fmt"
//函數(shù) 1
func portal1(channel1 chan string){
for i := 0; i <= 3; i++{
channel1 <- "Welcome to channel 1"
}
}
//函數(shù) 2
func portal2(channel2 chan string){
channel2 <- "Welcome to channel 2"
}
func main() {
//創(chuàng)建通道
R1:= make(chan string)
R2:= make(chan string)
//使用goroutine方式調(diào)用函數(shù)1和2
go portal1(R1)
go portal2(R2)
//隨機選擇一種
select{
case op1:= <- R1:
fmt.Println(op1)
case op2:= <- R2:
fmt.Println(op2)
}
}輸出:
Welcome to channel 2