示例1:
    select + default实现非阻塞式的获取
    select:哪个case语句执行得快,就执行哪个case语句;如果没有case语句执行,就执行default
    在本示例中,由于c1和c2都为nil,所以两个case语句不执行,而是执行default语句。

    1. package main
    2. import "fmt"
    3. func main() {
    4. var c1, c2 chan int // c1 and c2 = nil
    5. for {
    6. select {
    7. case n := <-c1: // 当c1为nil时,该case语句不会执行
    8. fmt.Println("Received from c1:", n)
    9. case n:= <-c2: // 当c2为nil时,该case语句不会执行
    10. fmt.Println("Received from c2:", n)
    11. default:
    12. fmt.Println("No value received") // No value received
    13. }
    14. }
    15. }

    示例2:

    func generator() chan int {
        out := make(chan int)
        go func() {
            i := 0
            for {
                time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond) // sleep 0-1500ms
                out <- i
                i++
            }
        }()
        return out
    }
    
    func worker(id int, c chan int) {
        for n := range c {
            time.Sleep(time.Second)
            fmt.Printf("Worker %d received %d\n", id, n)
        }
    }
    
    func createWorker(id int) chan<- int {
        c := make(chan int)
        go worker(id, c)
        return c
    }
    
    func main() {
        var c1, c2 = generator(), generator()
        var worker = createWorker(0)
    
        var values []int
        for {
            var activeWorker chan<- int // activeWorker = nil
            var activeValue int
            if len(values) > 0 {
                activeWorker = worker
                activeValue = values[0]
            }
    
            select {
            case n := <-c1:
                values = append(values, n)
            case n := <-c2:
                values = append(values, n)
            case activeWorker <- activeValue: // 当activeWorker为nil时,该case语句不会执行
                values = values[1:]
            }
        }
    }
    

    示例3:计时器的使用
    time.After(x) -> 返回一个channel,x时间后会往该channel中发送一个值
    time.Tick(x) -> 返回一个channel,每隔x时间往该channel里送一个值

    func generator() chan int {
        out := make(chan int)
        go func() {
            i := 0
            for {
                time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond) // sleep 0-1500ms
                out <- i
                i++
            }
        }()
        return out
    }
    
    func worker(id int, c chan int) {
        for n := range c {
            time.Sleep(time.Second)
            fmt.Printf("Worker %d received %d\n", id, n)
        }
    }
    
    func createWorker(id int) chan<- int {
        c := make(chan int)
        go worker(id, c)
        return c
    }
    
    func main() {
        var c1, c2 = generator(), generator()
        var worker = createWorker(0)
    
        var values []int
        tm := time.After(10 * time.Second)
        tick := time.Tick(time.Second)
    
        for {
            var activeWorker chan<- int // activeWorker = nil
            var activeValue int
            if len(values) > 0 {
                activeWorker = worker
                activeValue = values[0]
            }
    
            select {
            case n := <-c1:
                values = append(values, n)
            case n := <-c2:
                values = append(values, n)
            case activeWorker <- activeValue: // 当activeWorker为nil时,该case语句不会执行
                values = values[1:]
            case <-time.After(800 * time.Millisecond): // 如果800ms后还没获得数据,则打印"timeout"
                fmt.Println("timeout")
            case <-tick: // 每秒钟查看一次队列长度
                fmt.Println("queue len =", len(values))
            case <-tm: // 10秒钟后退出程序
                fmt.Println("bye")
                return
            }
        }
    }