The problem

What happens when I read and write to an uninitialized chan? Why is that?

How to answer

Reading and writing uninitialized Chan blocks.

For example,

1. Write uninitialized chan
package main
// Write uninitialized chan
func main(a) {
 var c chan int
 c <- 1
} Copy the code
// Output the result
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send (nil chan)]:
main.main()
 /Users/admin18/go/src/repos/main.go:6 +0x36 Copy the code

Notice this chan send (nil chan), which we’ll talk about in a second.

2. Write and read uninitialized chan
package main
import "fmt"
// Read uninitialized chan
func main(a) {
 var c chan int
 num, ok := <-c  fmt.Printf(Num =%v, ok=%v\n, num, ok) } Copy the code
// Output the result
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive (nil chan)]:
main.main()
 /Users/admin18/go/src/repos/main.go:6 +0x46 Copy the code

Notice this chan receive (nil chan), which we’ll talk about in a second.

Ask more

There are many interview questions about Chan, and this is one of the more common ones. But one more question: why does it block on uninitialized chan?

1. For writing

/ / in the SRC/runtime/chan. Go
func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool {
 if c == nil {
      // Cannot block. Return false to indicate that the message was not sent successfully
      if! block { return false  }  gopark(nil.nil, waitReasonChanSendNilChan, traceEvGoStop, 2)  throw("unreachable")  }  // omit other logic } Copy the code
  • UninitializedchanThis is going to be equal tonilWhen it cannot block, return directlyfalse, said writechanfailure
  • whenchanIf it can block, block directlygopark(nil, nil, waitReasonChanSendNilChan, traceEvGoStop, 2)And then callthrow(s string)Throws an error wherewaitReasonChanSendNilChanThat’s the error I just mentioned"chan send (nil chan)"

2. For reading

/ / in the SRC/runtime/chan. Go
func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) {
    // omit logic...
    if c == nil {
        if! block { return  }  gopark(nil.nil, waitReasonChanReceiveNilChan, traceEvGoStop, 2)  throw("unreachable")  }  // omit logic... } Copy the code
  • UninitializedchanThis is going to be equal tonilWhen it cannot block, return directlyfalseRead, saidchanfailure
  • whenchanIf it can block, block directlygopark(nil, nil, waitReasonChanReceiveNilChan, traceEvGoStop, 2)And then callthrow(s string)Throws an error wherewaitReasonChanReceiveNilChanThat’s the error I just mentioned"chan receive (nil chan)"

Article recommendation:

  • Golang interview question: How do reflect get field tag? Why can’t json packages export tags for private variables?
  • Golang: What happens to json package variables without tags?
  • Golang interview question: How to avoid memory escape?
  • Golang interview question: What about memory escape?
  • Golang: Does memory copy happen when a string is converted into a byte array?
  • Golang interview question: Flip containsChinese characters, numbers and English lettersThe string
  • Golang: Is it necessarily more expensive to copy a large slice than a small one?
  • Golang: What’s the difference between uintptr and unsafe.Pointer?
If you want to study one point of knowledge every day?

This article is formatted using MDNICE