版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36431213/article/details/83311028
在 Go
中我们所以 close()
来关闭一个 channel
- 官方的注释如下
The close built-in function closes a channel, which must be either bidirectional or send-only.
It should be executed only by the sender,never the receiver, and has the effect of shutting down the channel after the last sent value is received.
After the last value has been received from a closed channel c, any receive from c will succeed without blocking, returning the zero value for the channel element.
The form x, ok := <-c will also set ok to false for a closed channel.
翻译如下
close
内置函数关闭一个通道,该通道必须是双向的或仅发送的。- 如下关闭
ch3
就会报错invalid operation: close(ch3) (cannot close receive-only channel)
- 如下关闭
ch1 := make(chan int, 10)
ch2 := make(chan<- int, 10)
ch3 := make(<-chan int, 10)
close(ch1)
close(ch2)
close(ch3)
channel
应仅由发送方执行,而不应由接收方执行,并且在收到最后发送的值后具有关闭通道的效果。- 即
channel
应该由发送的一方执行,由接收channel
的一方关闭
- 即
func send(ch chan int) {
for i := 0; i < 10; i++ {
ch <- i
}
}
func receive(ch chan int) {
for {
fmt.Println(<-ch)
}
close(ch)
}
func main() {
ch := make(chan int, 10)
go send(ch)
go receive(ch)
time.Sleep(1 * time.Millisecond)
}
- 在从闭合通道
c
接收到最后一个值之后,来自c
的任何接收都将成功而不会阻塞,返回通道元素的零值。- 如下,因为通道元素类型是int,零值是0,所以输出全是
ch
的this is from ch 0
,而ch1
由于没有赋值,所以没有IO
操作不能被select
捕捉
- 如下,因为通道元素类型是int,零值是0,所以输出全是
func receive(ch chan int, ch1 chan int) {
for {
select {
case a := <-ch:
fmt.Println("this is from ch", a)
case b := <-ch1:
fmt.Println("this is from ch1", b)
}
}
}
func main() {
ch := make(chan int, 10)
ch1 := make(chan int, 10)
close(ch)
go receive(ch, ch1)
time.Sleep(1 * time.Millisecond)
}
- 对于封闭的通道,表单
x , ok := <- c
也会将ok
设置为false
- 输出
0
和false
,通过这一点我们可以判断channel
是否被关闭
- 输出
ch := make(chan int, 10)
close(ch)
if x, ok := <-ch; !ok {
fmt.Println(x, ok)
}