channel取数据时未被赋值将被阻塞,可以使用这一机制来完成事件的监听
wg := new(sync.WaitGroup) wg.Add(2) event := make(chan bool) //函数 go func() { defer wg.Done() for i := 0; i < 5; i++ { fmt.Println("触发事件前", i) } event <- true //触发事件 }() go func() { <-event defer wg.Done() for i := 0; i < 5; i++ { fmt.Println("触发事件后", i) } }() wg.Wait()
输出:
触发事件前 0
触发事件前 1
触发事件前 2
触发事件前 3
触发事件前 4
触发事件后 0
触发事件后 1
触发事件后 2
触发事件后 3
触发事件后 4
在使用Channel时要注意
如果chan的容量已满,将会发生死锁
如:
data:=make(chan int ,3) exit:=make(chan bool) data<-1 data<-2 data<-3 data<-4//运行到这里将被阻塞,因为chan容量已满
len返回chan中未被读取的元素数量,cap返回缓冲区大小,close关闭当前chan
判断chan是否关闭
for{ if d,ok:=<-data;ok}{ fmt.Println(d) }else{ break } }
单向chan:只负责接收,或者只负责发送
相当于分离了chan的发送和接收,将其变为两个便于控制的变量
c := make(chan int, 3) var send chan<- int = c // send-only var recv <-chan int = c // receive-only send <- 1 <-recv