ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] select是Go语言中的一个控制语句,它有select,case, default共同构成,与switch的书写方式类似。**select只用来操作的channel的读写操作**。 *select 的特性* 1. 如果只有一个 case 语句评估通过,那么就执行这个case里的语句 2. 如果有多个 case 语句评估通过,那么通过随机的方式随机选一个 3. 如果 default 外的 case 语句都没有通过评估,那么执行 default 里的语句 4. 如果没有 default,那么 代码块会被阻塞,直到有一个 case 通过评估;否则一直阻塞 ## 示例1(多路select复用) ```go var ( swg sync.WaitGroup ) var ch1 = make(chan int, 3) var ch2 = make(chan string, 3) // 生产数据 func testProducer(i int) { defer swg.Done() // 多个case都符合的话,随机选择一个case执行 select { case ch1 <- i: fmt.Printf("ch1 send %v\n", i) case ch2 <- fmt.Sprintf("test%02d", i): fmt.Printf("ch2 send %v\n", fmt.Sprintf("test%02d", i)) } } // 消费数据 func testConsumer() { defer swg.Done() select { case i := <-ch1: fmt.Printf("ch1 received is %v\n", i) case s := <-ch2: fmt.Printf("ch2 received is %v\n", s) } } func main() { for i := 0; i < 10; i++ { swg.Add(1) go testProducer(i) } for i := 0; i < 4; i++ { swg.Add(1) go testConsumer() } swg.Wait() } // 运行结果 // ch1 send 3 // ch1 send 0 // ch1 send 2 // ch2 send test09 // ch2 received is test09 // ch1 received is 2 // ch2 send test01 // ch1 received is 3 // ch1 received is 0 // ch2 send test04 // ch1 send 7 // ch2 send test05 // ch1 send 8 // ch1 send 6 ``` ## 示例2(超时案例) ```go package main import ( "fmt" "sync" "time" ) var ( swg sync.WaitGroup ) func sendChan(ch chan string) { swg.Add(1) go func() { for i := 0; i < 5; i++ { // 休眠 i 秒 for j := 0; j < i; j++ { time.Sleep(time.Millisecond * 1000) } ch <- fmt.Sprintf("chan%02d", i) } swg.Done() }() } func main() { ch := make(chan string, 5) defer close(ch) defer swg.Wait() sendChan(ch) for j := 0; j < 5; j++ { select { case s := <-ch: fmt.Printf("ch received %v\n", s) case <-time.After(time.Second * 3): fmt.Println("Channel no data for more than three seconds") return } } } // 运行结果 // ch received chan00 // ch received chan01 // ch received chan02 // Channel no data for more than three seconds ```