📜  在 Go 语言中选择语句

📅  最后修改于: 2021-10-25 02:07:22             🧑  作者: Mango

在 Go 语言中,select 语句就像 switch 语句,但在 select 语句中,case 语句是指通信,即通道上的发送或接收操作。

句法:

select{

case SendOrReceive1: // Statement
case SendOrReceive2: // Statement
case SendOrReceive3: // Statement
.......
default: // Statement

要点:

  • Select 语句等待通信(发送或接收操作)准备好开始某些情况。

    例子:

    // Go program to illustrate the
    // concept of select statement
    package main
       
    import("fmt"
     "time")
           
        // function 1
        func portal1(channel1 chan string) {
      
            time.Sleep(3*time.Second)
            channel1 <- "Welcome to channel 1"
        }
           
        // function 2
         func portal2(channel2 chan string) {
      
            time.Sleep(9*time.Second)
            channel2 <- "Welcome to channel 2"
        }
       
    // main function
    func main(){
           
        // Creating channels
       R1:= make(chan string)
       R2:= make(chan string)
          
       // calling function 1 and 
       // function 2 in goroutine
       go portal1(R1)
       go portal2(R2)
      
       select{
      
            // case 1 for portal 1
           case op1:= <- R1:
           fmt.Println(op1)
       
           // case 2 for portal 2
           case op2:= <- R2:
           fmt.Println(op2)
       }
          
    }
    

    输出:

    Welcome to channel 1

    说明:在上述程序中,传送门 1 休眠 3 秒,传送门 2 休眠 9 秒,它们将在休眠时间结束后准备继续。现在,select 语句一直等到他们的睡眠时间,当门户 2 醒来时,它选择案例 2 并打印“欢迎来到频道 1”。如果门户 1 在门户 2 之前醒来,则输出是“欢迎来到频道 2”。

  • 如果 select 语句不包含任何 case 语句,则该 select 语句将永远等待。

    句法:

    select{}

    例子:

    // Go program to illustrate the
    // concept of select statement
    package main
      
    // main function
    func main() {
          
        // Select statement 
       // without any 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 语句时执行此语句。

    例子:

    // Go program to illustrate the
    // concept of select statement
    package main
      
    import "fmt"
      
    // main function
    func main() {
          
        // creating channel
        mychannel:= make(chan int)
       select{
         case <- mychannel: 
           
         default:fmt.Println("Not found")
    }   
    }
    

    输出:

    Not found
  • select语句的阻塞是指当没有准备好的case语句并且select语句不包含任何default语句时,select语句阻塞,直到至少有一个case语句或通信可以进行。

    例子:

    // Go program to illustrate the
    // concept of select statement
    package main
      
    // main function
    func main() {
          
        // creating channel
        mychannel:= make(chan int)
          
        // channel is not ready 
       // and no default case
       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 语句中,如果有多个 case 准备进行,则可以随机选择其中一个。

    例子:

    // Go program to illustrate the
    // concept of select statement
    package main
      
    import "fmt"
          
          
        // function 1
        func portal1(channel1 chan string){
            for i := 0; i <= 3; i++{
                channel1 <- "Welcome to channel 1"
            }
              
        }
          
        // function 2
         func portal2(channel2 chan string){
            channel2 <- "Welcome to channel 2"
        }
      
    // main function
    func main() {
          
        // Creating channels
       R1:= make(chan string)
       R2:= make(chan string)
         
       // calling function 1 and 
       // function 2 in goroutine
       go portal1(R1)
       go portal2(R2)
         
       // the choice of selection 
       // of case is random
       select{
           case op1:= <- R1:
           fmt.Println(op1)
           case op2:= <- R2:
           fmt.Println(op2)
       }
    }
    

    输出:

    Welcome to channel 2