在某些场景下咱们须要同时从多个通道接收数据。通道在接收数据时,如果没有数据能够接管将会产生阻塞,而select就能够同时监听一个或多个channel,直到其中一个channel筹备好。

select的应用相似于switch语句,它有一系列case分支和一个默认的分支。每个case会对应一个通道的通信(接管或发送)过程。select会始终期待,直到某个case的通信操作实现时,就会执行case分支对应的语句。具体格局如下:

    select {    case <-chan1:       // 如果chan1胜利读到数据,则进行该case解决语句    case chan2 <- 1:       // 如果胜利向chan2写入数据,则进行该case解决语句    default:       // 如果下面都没有胜利,则进入default解决流程    }
package mainimport (    "fmt"    "time")func test1(ch chan string) {    time.Sleep(time.Second * 1)    ch <- "test1"}func test2(ch chan string) {    time.Sleep(time.Second * 2)    ch <- "test2"}func main() {    // 2个管道    output1 := make(chan string)    output2 := make(chan string)    // 跑2个子协程,写数据    go test1(output1)    go test2(output2)    for {        // 用select监控        select {        case s1 := <-output1:            fmt.Println("s1=", s1)        case s2 := <-output2:            fmt.Println("s2=", s2)        default:            ticker := time.NewTicker(1 * time.Second)            fmt.Printf("%v\n", <-ticker.C)        }    }}

判断通道是否曾经存满

package mainimport (    "fmt"    "time")// 判断管道有没有存满func main() {    // 创立管道    output1 := make(chan string, 1)    // 子协程写数据    go write(output1)    // 取数据    for s := range output1 {        fmt.Println("res:", s)        time.Sleep(time.Second)    }}func write(ch chan string) {    for {        select {        // 写数据        case ch <- "hello":            fmt.Println("write hello")        default:            fmt.Println("channel full")        }        time.Sleep(time.Millisecond * 500)    }}