for select switch遍历channel
之前在做测试的时候,写过这样一个协程的例子,运行之后发现Recive函数一直没有退出
func main() {
flag := make(chan int,1)
msg := make(chan interface{},100)
go Send(msg)
go Recive(msg)
<-flag
}
func Send(msgChan chan interface{}) {
msgChan<-Msg{Name:"test"}
msgChan<-"close"
}
func Recive(msgChan chan interface{}) {
for {
select {
case msg := <-msgChan:
switch msg.(type) {
case Msg:
log.Println("type Msg",msg)
case string:
log.Println("type string",msg)
if msg=="close" {
close(msgChan)
break
}
}
default:
log.Println("select")
}
log.Println("for")
}
}
运行结果如下:
2019/09/12 22:08:46 type Msg {test}
2019/09/12 22:08:47 for
2019/09/12 22:08:47 type string close
2019/09/12 22:08:48 for
2019/09/12 22:08:49 for
2019/09/12 22:08:50 for
......
2019/09/12 22:10:28 for
发现Recive在接收到close的消息之后进行了break,但是只是break出了select的代码块,for循环依然在运行,因此直接break是无法跳出for循环,需要使用break 标签这种方式来中断
func Recive(msgChan chan interface{}) {
L:
for {
select {
case msg := <-msgChan:
switch msg.(type) {
case Msg:
log.Println("type Msg",msg)
case string:
log.Println("type string",msg)
if msg=="close" {
close(msgChan)
break L
}
}
default:
time.Sleep(time.Second)
log.Println("select")
}
time.Sleep(time.Second)
log.Println("for")
}
}