go语言中的select语句(译)

185 阅读2分钟

这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战

原文链接:www.geeksforgeeks.org/select-stat…

在go语言中,select语句就像switch语句,但是在select语句中,case语句适用于通信,例如,在管道上发送或者接收操作。

语法

select{

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

重点

  • select语句会一直等待,直到有一些case准备好要开始通信了(发送或者接收操作)。

例子

// 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睡了3s,入口2睡了9s,当它们的睡时间结束后,它们就准备好执行了。现在,select语句一直在等待它们的睡眠时间结束,当入口2醒来后,它选择了case2然后打印了"Welcome to channel 1"。如果入口1在入口2之前醒来,然后输出就会是"Welcome to channel 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