reflect.MakeChan
reflect.Select
reflect.SelectCase
package main
import (
"context"
"fmt"
"reflect"
"sync"
"time"
)
func main() {
ch := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, reflect.TypeOf(0)), 10)
ch.Send(reflect.ValueOf(1)) // 向管道发送数据
ch.Send(reflect.ValueOf(2))
ch.Send(reflect.ValueOf(3))
recv, ok := ch.Recv() // 接收返回值 等价于 v, ok := <-ch
fmt.Println("---------", recv, ok)
fmt.Println(ch.TrySend(reflect.ValueOf(100))) // 尝试发送
fmt.Println(ch.TryRecv()) // 尝试接收
//ch.Close() //关闭管道
ctx, _ := context.WithTimeout(context.Background(), time.Second*2)
wg := &sync.WaitGroup{}
wg.Add(1)
go Do(ctx, ch, wg)
wg.Wait()
}
func Do(ctx context.Context, ch reflect.Value, wg *sync.WaitGroup) {
defer wg.Done()
cases := []reflect.SelectCase{
{
Dir: reflect.SelectRecv, // 等价于 case <-ch:
Chan: ch,
},
{
Dir: reflect.SelectRecv, // 等价于 case <-ctx.Done:
Chan: reflect.ValueOf(ctx.Done()),
},
{
Dir: reflect.SelectSend, // 等价于 case ch<-100:
Chan: ch,
Send: reflect.ValueOf(100),
},
{
Dir: reflect.SelectDefault, // 等价于 default:
//Chan: reflect.Value{},
//Send: reflect.Value{},
},
}
for {
closen, recv, recvOk := reflect.Select(cases) //closen 命中的分支, recv 接收时的返回值, recvOk 接受时通道是否关闭
switch closen {
case 0:
fmt.Println("case0 分支命中:", recv, recvOk)
case 1:
fmt.Println("case1 分支命中,下线信号", recvOk) // 监听context的分支 和 default分支保留一个即可
fmt.Println("下线")
return
case 2:
fmt.Println("case2 分支命中,发送数据")
//case 3:
// fmt.Println("default 分支命中")
}
}
}