https://gobyexample.com/non-blocking-channel-operations

In the example indicated by this link:

package main import "fmt" func main() { messages := make(chan string) signals := make(chan bool) select { case msg := <-messages: fmt.Println("received message", msg) default: fmt.Println("no message received") } msg := "hi" select { case messages <- msg: fmt.Println("sent message", msg) default: fmt.Println("no message sent") } select { case msg := <-messages: fmt.Println("received message", msg) case sig := <-signals: fmt.Println("received signal", sig) default: fmt.Println("no activity") } } 

Output:

 no message received no message sent no activity 

Hence the question: why do not we get into this block?

 case messages <- msg: fmt.Println("sent message", msg) 

After all, we write the string "hi" in msg

    1 answer 1

    Because there is no one to send the message.

    In Go, by default, channels are not buffered and do not hold messages that cannot be delivered immediately. Therefore, the normal send operation in this case will block the stream (until the recipient appears).

    And the implementation of a non-blocking send select in this situation transfers control to the default label and does not send a message.

    See the explanation for an example on multithreading :

    It is ready. This allows goroutines to synchronize variables.

    By default, send and receive operations are blocked until the other party is ready. This allows gorutins to synchronize without explicit locks or variables for conditions.

    • Thank you for responding, please explain, and in the 3rd select-e he does not see the recipient due to different scopes? This is where case msg: = <-messages: fmt.Println ("received message", msg) - Kenshi
    • @Kenshi is the same; nobody sends anything to all these channels at this moment. - D-side