Golang: Language: Concurrency: Select Dynamic Channels

27th October 2021 at 4:09pm

Go 的 select 语句可以选中多个已知的 channel 变量。但是假如你要 select 的 channel 并不是固定的,比如放在一个 slice 中,那么你需要用 reflect.Select 函数来实现。

这个函数不难理解。这里有一个简单的代码例子:

package main

import (
    "fmt"
    "reflect"
    "time"
)

func main() {
    var cases []reflect.SelectCase
    var chs []chan int
    for i := 0; i < 4; i++ {
        chs = append(chs, make(chan int, 10))
        cases = append(cases, reflect.SelectCase{
            Dir:  reflect.SelectRecv,
            Chan: reflect.ValueOf(chs[i]),
        })
    }

    go func() {
        n := 0
        for {
            for i := 0; i < 4; i++ {
                chs[i] <- n
                n++

                time.Sleep(1 * time.Second)
            }
        }
    }()

    for {
        i, v, ok := reflect.Select(cases)
        fmt.Printf("Chan %d: received %d, %t\n", i, v.Int(), ok)
    }
}