通过在Go中使用select来发送到频道有什么好处?

Ale*_*lex 3 go

在Gorilla websocket的示例目录中,有一个名为hub.go的文件.

https://github.com/gorilla/websocket/blob/master/examples/chat/hub.go

在这里,您可以在类型集线器上找到执行此操作的方法.

func (h *hub) run() {
    for {
        select {
        case c := <-h.register:
            h.connections[c] = true
        case c := <-h.unregister:
            if _, ok := h.connections[c]; ok {
                delete(h.connections, c)
                close(c.send)
            }
        case m := <-h.broadcast:
            for c := range h.connections {
                select {
                case c.send <- m:
                default:
                    close(c.send)
                    delete(h.connections, c)
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么它不仅仅是像这样在最后一个案例中直接发送到c.send频道?

case m := <-h.broadcast:
    for c := range h.connections {
        c.send <- m
    }
Run Code Online (Sandbox Code Playgroud)

sis*_*oft 6

这是保证非阻塞发送到频道的方法.如果c.send chan现在无法接受新消息,则将执行默认分支.没有select {}块可以阻止发送到无缓冲或完全填充的缓冲通道.