Non Blocking Channel Operations

Non-Blocking Channel Operations #

// Envios e recebimentos básicos nos canais, são bloqueantes.
// No entanto, é possível usar o `select` com uma cláusula `default`
// para implementar envio e recebimentos _non-blocking_ e até
// non-blocking `select` de multiplos casos.

package main

import "fmt"

func main() {
	messages := make(chan string)
	signals := make(chan bool)

	// Aqui está um recebimento não bloqueante. Se um valor
	// estiver disponível em `messages` o `select` prosseguirá
	// com o `case` que tem o `<-messages`. Se não,
	// presseguirá com o case padrão ou `default`.
	select {
	case msg := <-messages:
		fmt.Println("received message", msg)
	default:
		fmt.Println("no message received")
	}

	// Um send não bloqueante funciona de maneira similar.
	// Aqui, `msg` não pode ser enviado para o canal `messages`,
	// justamente porque o canal não tem buffer e
	// não tem um recebimento. Portanto, o case `default`
	// será executado.
	msg := "hi"
	select {
	case messages <- msg:
		fmt.Println("sent message", msg)
	default:
		fmt.Println("no message sent")
	}

	// É possível utilizar multiplos `case`s acima da clausula
	// `default`. Aqui está uma tentativa de recebimento não bloqueante
	// em ambos os canais  `messages` and `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