在Go语言中,select语句类似于switch语句,但是在select语句中,case语句指的是通信,即通道上的发送或接收操作。
语法:
select{
case SendOrReceive1: // 语句
case SendOrReceive2: // 语句
case SendOrReceive3: // 语句
.......
default: // 语句重要事项:
Select语句等待通信(发送或接收操作)准备就绪,以便在某些情况下开始。
package main
import (
    "fmt"
    "time"
)
// 函数 1
func portal1(channel1 chan string) {
    time.Sleep(3 * time.Second)
    channel1 <- "Welcome to channel 1"
}
// 函数 2
func portal2(channel2 chan string) {
    time.Sleep(9 * time.Second)
    channel2 <- "Welcome to channel 2"
}
func main() {
    // 创建通道
    R1 := make(chan string)
    R2 := make(chan string)
    // 使用goroutine调用函数1和函数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秒,在它们的休眠时间结束后,它们将准备继续进行。现在,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语句准备进行时,将执行此语句。
package main
import "fmt"
func main() {
    //创建通道
    mychannel := make(chan int)
    select {
    case <-mychannel:
    default:
        fmt.Println("Not found")
    }
}输出:
Not found
select语句的阻塞意味着当尚无case语句准备就绪且select语句不包含任何default语句时,则select语句将阻塞,直到至少一个case语句或通信则可以继续。
package main
func main() {
    //创建通道
    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"
      
      
    //函数 1 
    func portal1(channel1 chan string){ 
        for i := 0; i <= 3; i++{ 
            channel1 <- "Welcome to channel 1"
        } 
          
    } 
      
    //函数 2 
     func portal2(channel2 chan string){ 
        channel2 <- "Welcome to channel 2"
    } 
  
func main() { 
      
    //创建通道 
   R1:= make(chan string) 
   R2:= make(chan string) 
     
   //使用goroutine方式调用函数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