【问题标题】:Channel is not closing properly?频道没有正常关闭?
【发布时间】:2021-01-22 19:37:38
【问题描述】:

从我在这里读到的与遇到类似问题的人一起阅读的内容,显然,频道没有关闭。我尝试了多种关闭频道的方法,但仍然出现此错误。

预期行为:当我在控制台中输入“QUIT”时,退出程序而不会出错

当前行为:当我在控制台中输入“QUIT”时,出现此错误

panic: close of nil channel 
goroutine 6 [running]:
 main.main.func1(0xc000010200, 0xc00006e060, 0x0, 0x0)
    /home/greg/go/src/challenges/hydraChat/simplechat/simpleChat.go:24 +0xd7
created by main.main
    /home/greg/go/src/challenges/hydraChat/simplechat/simpleChat.go:18 +0x88
exit status 2

这里是代码。

type room struct {
MessageCH chan string
People    map[chan<- string]struct{}
Quit      chan struct{}

}

func main() {
    room := room{MessageCH: make(chan string)}
    enter code here
    var msg string

    go func() {
        for {
            fmt.Scan(&msg)

            room.MessageCH <- msg
            if msg == "QUIT" {
                close(room.Quit)
                return
            }
        }

    }()
    go func() {
        for msg := range room.MessageCH {
            fmt.Println("message received: ", msg)
        }
        defer close(room.MessageCH)
    }()

    <-room.Quit

}

【问题讨论】:

  • 关闭 nil 通道听起来更像是通道未初始化 (nil) 或已关闭(从未在代码中尝试过以查看其内容)。所以它看起来正确关闭。我没有看到 room.Quit 的初始化代码。

标签: go concurrency channel goroutine


【解决方案1】:

频道的Zero valuenil,关闭nil 频道会发生恐慌,就像您所经历的那样。

Spec: Close:

关闭nil 频道也会导致run-time panic

您尝试关闭room.Quit,但您从未为其分配任何值。

当你像这样创建room 时这样做:

room := room{
    MessageCH: make(chan string),
    Quit:      make(chan struct{}),
}

有关通道公理,请参阅How does a non initialized channel behave?

还请注意,它不会在此处引起问题,但您不应将变量命名为与其类型完全相同:room := room{...}。在此声明之后,您不能再引用 room 类型,该标识符将被隐藏(直到包含块的末尾)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-14
    • 2021-11-14
    • 2020-04-26
    • 1970-01-01
    • 2016-12-26
    相关资源
    最近更新 更多