go-reflect.Select使用
type SelectCase struct {
Dir SelectDir // direction of case
Chan Value // channel to use (for send or receive)
Send Value // value to send (for send)
}
SelectCase描述了select操作中的一种case。
case种类取决于Dir
如果Dir是SelectDefault,代表case中的default case,
Chan和Send都必须为0值。
如果Dir是SelectSend,代表send case,
则Chan的隐含值必须是channel,Send的隐含值必须可赋值给channel的元素类型。
特殊情况下,如果Chan为0值,则该case被忽略,Send也被忽略,send可能为0值或非0值。
如果Dir是SelectRecv,代表recv case。
则Chan的隐含值必须是channel,Send为0值。
如果Chan为0值,该case被忽略,Send必须也为0值。
当一个recv case被选中,receive到的值被Select返回。
func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool)
select函数接收electCase列表作为参数,直到列表中某个case发生才返回。
返回case的index索引,如果是recv case也返回Value和recvOK标志。
总结:使用chan构建select case时,如果是send,则Dir为reflect.SelectSend, Chan为此Chan,Send参数为要发送的值;如果是recv,则Dir为reflect.SelectRecv, Chan为此Chan,Send不赋值。
// createCases 将多个chan作为case clause
func createCases(chs ...chan int) []reflect.SelectCase {
var cases []reflect.SelectCase
// 添加recv case
for _, ch := range chs {
cases = append(cases, reflect.SelectCase{
Dir: reflect.SelectRecv,
Chan: reflect.ValueOf(ch), // Chan字段使用反射
})
}
for i, ch := range chs {
v := reflect.ValueOf(i + 100)
cases = append(cases, reflect.SelectCase{
Dir: reflect.SelectSend,
Chan: reflect.ValueOf(ch),
Send: v,
})
}
return cases
}
func main() {
ch1 := make(chan int, 50)
ch2 := make(chan int, 50)
cases := createCases(ch1, ch2)
ch1 <- 100
ch2 <- 200
close(ch1)
close(ch2)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
for {
chosen, recv, ok := reflect.Select(cases)
if recv.IsValid() { // recv case
if ok {
fmt.Printf("recv data case from index[%v], Value: %v, ok: %v\n", chosen, recv, ok)
}else{
fmt.Printf("recv close case from index[%v], Value: %v, ok: %v\n", chosen, recv, ok)
// 已close的chan的receive和send都移除
}
}else { // send case
//fmt.Println("send:", chosen, recv, ok)
fmt.Printf("send case from index[%v], Value: %v, ok: %v\n", chosen, recv, ok)
}
}
}()
wg.Wait()
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术