1、关闭已经关闭的 channel 会引发 panic,panic: close of closed channel
ch3 := make(chan int, 3)
wg.Add(1)
go func() {
for i := 1; i < 3; i++ {
ch3 <- i
}
close(ch3)
close(ch3)
// panic: close of closed channel
wg.Done()
}()
wg.Wait()
2、对已关闭的 channel 进行写会引发 panic,panic: send on closed channel
ch4 := make(chan int, 5)
wg.Add(1)
go func() {
for i := 1; i < 5; i++ {
ch4 <- i
}
close(ch4)
ch4 <- 5
// panic: send on closed channel
wg.Done()
}()
wg.Wait()
3、 对已关闭的 channel 进行读:
- 无缓冲的 channel,获得零值
ch2 := make(chan int)
go func() {
ch2 <- 1
close(ch2)
}()
for i := 0; i < 3; i++ {
v, ok := <-ch2
fmt.Println(i, v, ok)
}
- 有缓冲的 channel
- 如果数据尚未读完,则获取数据
- 如果数据处理完,则获取 0 值
怎么区分是缓存中的 0 值,还是因为关闭后返回的 0 值
通过 value, ok := ←chan
如果 ok 为 true 的时候就是缓存中的 0 值
否则是因为关闭后返回的 0 值
ch1 := make(chan int, 3)
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
for i := 1; i < 3; i++ {
ch1 <- i
}
close(ch1)
wg.Done()
}()
wg.Wait()
for i := 1; i < 5; i++ {
v, ok := <- ch1
fmt.Println(i, v, ok)
}