select

select特点

当 select 中的其他条件分支都没有准备好的时候,default 分支会被执行。

每个case语句里必须是一个IO操作,确切的说,应该是一个面向channel的IO操作。

实例1

测试当 select 中的其他条件分支都没有准备好的时候,default 分支会被执行。

package main

import (

"fmt"

"time"

)

func main() {

        tick := time.Tick(1e8)   //定时1s

        boom := time.After(5e8)  //定时5s

        for {

                select {

                case <-tick:

                        fmt.Println("tick.")

                case <-boom:

                        fmt.Println("BOOM!")

                        return

                default:

                        fmt.Println("    .")

                        time.Sleep(5e7)  //定时500ms

                }

        }

}

实例2

测试没有default分支时select,每个case都是io操作,相当于一个while循环

ch1 := make (chan int, 1)

ch2 := make (chan int, 1)

...

select {

case <-ch1:

    fmt.Println("ch1 pop one element")

case <-ch2:

    fmt.Println("ch2 pop one element")

}

实例3

【使用 select 实现 timeout 机制】

当超时时间到的时候,case2 会操作成功。所以 select 语句则会退出。而不是一直阻塞在 ch 的读取操作上。从而实现了对 ch 读取操作的超时设置。

timeout := make (chan bool, 1)

go func() {

    time.Sleep(1e9) // sleep one second

    timeout <- true

}()

ch := make (chan int)

select {

case <- ch:

case <- timeout:

    fmt.Println("timeout!")

}

实例4

我们可以使用 select 语句来检测 chan 是否已经满了。

因为 ch 插入 1 的时候已经满了,当 ch 要插入 2 的时候,发现 ch 已经满了(case1 阻塞住),则 select 执行 default 语句。这样就可以实现对 channel 是否已满的检测,而不是一直等待。

ch := make (chan int, 1)

ch <- 1

select {

case ch <- 2:

default:

    fmt.Println("channel is full !")

}

你可能感兴趣的:(select)