Go 关闭 channel 的 close 方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 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,所以输出全是chthis is from ch 0 ,而 ch1由于没有赋值,所以没有 IO 操作不能被 select 捕捉
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
    • 输出 0false ,通过这一点我们可以判断 channel 是否被关闭
	ch := make(chan int, 10)
	close(ch)
	if x, ok := <-ch; !ok {
		fmt.Println(x, ok)
	}

猜你喜欢

转载自blog.csdn.net/qq_36431213/article/details/83311028