头图

概述

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

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
*/

联系我

公众号


洋芋土豆
1.1k 声望10 粉丝