Golang Channel nil#
Channel 在空值的时候会有特殊的行为。
与大多数的数据类型不同,Channel 在 nil
的情况下进行读写会发生线程阻塞,而不是空指针异常。
ReadNil#
package main
func main() {
var nilCh chan struct{} = nil
<- nilCh
}
// STDOUT
//
// fatal error: all goroutines are asleep - deadlock!
//
// goroutine 1 [chan receive (nil chan)]:
// main.main()
// /learn/codes/go/channel/readnil/read_nil_channel.go:5 +0x24
// exit status 2
WriteNil#
package main
func main() {
var nilCh chan struct{} = nil
nilCh <- struct{}{}
}
// STDOUT
//
// fatal error: all goroutines are asleep - deadlock!
//
// goroutine 1 [chan send (nil chan)]:
// main.main()
// /Users/uberate/workspace/learn/codes/go/channel/writenil/write_nil_channel.go:5 +0x24
// exit status 2
执行上述两个代码我们发现了一个现象,nil
状态下的 Channel 是无法读写的,会一直阻塞。
避免#
那有什么方式可以避免吗?实际上这个问题是一个 Go
陷阱。需要我们在所有 Read
或 Write
的时候,使用 select
关键字。
例如如下代码
package main
import (
"fmt"
)
func main() {
var nilCh chan struct{} = nil
select {
case <-nilCh:
// never reach here
fmt.Println("receive from nilCh")
default:
fmt.Println("default")
}
}
// STDOUT:
//
// default