Channel Close Check

概述 #

建议先阅读 非缓冲通道, 缓冲通道, 关闭通道, 通道方向

Go 语言没有提供函数或方法判断一个通道是否关闭。因此只能使用一个变通的办法:接收通道元素,根据返回的布尔值确定通道是否关闭。

例子 #

双向通道检测 #

package main

func main() {
	ch := make(chan string)
	close(ch)

	if _, open := <-ch; !open {
		println("channel closed")
	}
}

// $ go run main.go
// 输出如下
/**
  channel closed
*/

单向 (只读) 通道检测 #

package main

import "time"

func main() {
	ch := make(chan string)

	go func(c <-chan string) {
		if _, open := <-c; !open {
			println("channel closed")
		}
	}(ch)

	close(ch)
	time.Sleep(time.Second)
}

// $ go run main.go
// 输出如下
/**
  channel closed
*/

单向 (只写) 通道检测 #

对于只写通道,需要采用一个折中的办法:

  • 尝试向通道写入数据
    • 如果写入成功,说明通道还未关闭
    • 写入失败,发生 panic, 这时可以利用 deferrecover 中输出原因
package main

import "time"

func main() {
	ch := make(chan string)

	go func(c chan<- string) {
		defer func() {
			if err := recover(); err != nil { // 捕获到 panic
				println("channel closed")
			}
		}()

		c <- "hello world"
	}(ch)

	close(ch)
	time.Sleep(time.Second)
}

// $ go run main.go
// 输出如下,你的输出可能和这里的不一样
/**
  channel closed
*/

转载申请

本作品采用 知识共享署名 4.0 国际许可协议 进行许可,转载时请注明原文链接,图片在使用时请保留全部内容,商业转载请联系作者获得授权。

© 蛮荆 | 陕公网安备 61011302001681 号 | 陕ICP备2023004378号-1 | Rendered by Hugo