Go by Example: Non-Blocking Channel Operations

Los envíos y recepciones básicos en canales son bloqueantes. Sin embargo, podemos usar select con una cláusula default para implementar envíos, recepciones e incluso selects multi-dirección no bloqueantes.

package main
import "fmt"
func main() {
    messages := make(chan string)
    signals := make(chan bool)

Aquí hay una recepción no bloqueante. Si un valor está disponible en messages, entonces select tomará el caso <-messages con ese valor. Si no, inmediatamente tomará el caso default.

    select {
    case msg := <-messages:
        fmt.Println("received message", msg)
    default:
        fmt.Println("no message received")
    }

Un envío no bloqueante funciona de manera similar. Aquí msg no puede ser enviado al canal messages, porque el canal no tiene búfer y no hay receptor. Por lo tanto, se selecciona el caso default.

    msg := "hi"
    select {
    case messages <- msg:
        fmt.Println("sent message", msg)
    default:
        fmt.Println("no message sent")
    }

Podemos usar múltiples case por encima de la cláusula default para implementar un select no bloqueante de múltiples vías. Aquí intentamos recepciones no bloqueantes tanto en messages como en signals.

    select {
    case msg := <-messages:
        fmt.Println("received message", msg)
    case sig := <-signals:
        fmt.Println("received signal", sig)
    default:
        fmt.Println("no activity")
    }
}
$ go run non-blocking-channel-operations.go 
no message received
no message sent
no activity

Siguiente ejemplo: Closing Channels.