對未初始化的的 chan
進行讀寫,會怎麼樣?爲何?golang
讀寫未初始化的 chan
都會阻塞。web
package main
// 寫未初始化的chan func main() { var c chan int c <- 1 } 複製代碼
// 輸出結果
fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan send (nil chan)]: main.main() /Users/admin18/go/src/code.byted.org/linzhaolun/repos/main.go:6 +0x36 複製代碼
注意這個 chan send (nil chan)
,待會會提到。面試
package main
import "fmt" // 讀未初始化的chan func main() { var c chan int num, ok := <-c fmt.Printf("讀chan的協程結束, num=%v, ok=%v\n", num, ok) } 複製代碼
// 輸出結果
fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan receive (nil chan)]: main.main() /Users/admin18/go/src/code.byted.org/linzhaolun/repos/main.go:6 +0x46 複製代碼
注意這個 chan receive (nil chan)
,待會也會提到。json
關於 chan
的面試題很是多,這個是比較常見的其中一個。但多問一句:爲何對未初始化的 chan
就會阻塞呢?數組
1. 對於寫的狀況編輯器
//在 src/runtime/chan.go中
func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool { if c == nil { // 不能阻塞,直接返回 false,表示未發送成功 if !block { return false } gopark(nil, nil, waitReasonChanSendNilChan, traceEvGoStop, 2) throw("unreachable") } // 省略其餘邏輯 } 複製代碼
chan
此時是等於
nil
,當它不能阻塞的狀況下,直接返回
false
,表示寫
chan
失敗
chan
能阻塞的狀況下,則直接阻塞
gopark(nil, nil, waitReasonChanSendNilChan, traceEvGoStop, 2)
, 而後調用
throw(s string)
拋出錯誤,其中
waitReasonChanSendNilChan
就是剛剛提到的報錯
"chan send (nil chan)"
2. 對於讀的狀況學習
//在 src/runtime/chan.go中
func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) { //省略邏輯... if c == nil { if !block { return } gopark(nil, nil, waitReasonChanReceiveNilChan, traceEvGoStop, 2) throw("unreachable") } //省略邏輯... } 複製代碼
chan
此時是等於
nil
,當它不能阻塞的狀況下,直接返回
false
,表示讀
chan
失敗
chan
能阻塞的狀況下,則直接阻塞
gopark(nil, nil, waitReasonChanReceiveNilChan, traceEvGoStop, 2)
, 而後調用
throw(s string)
拋出錯誤,其中
waitReasonChanReceiveNilChan
就是剛剛提到的報錯
"chan receive (nil chan)"
中文、數字、英文字母
的字符串
本文使用 mdnice 排版ui