Concurrency · 3 MIN READ

default makes select try, not wait

Receive from a channel if a value is ready, and return if it is not.

The Tour's "Default Selection" page: a default case runs when no other case is ready, so the select returns instead of blocking. That is how you poll a channel, and how you try a send without parking the goroutine.

Without default, select waits. With it, "nothing ready" is a value you handle, not a hang. A busy loop of default-selects is a spin; use it for a single try, not as a substitute for a timer.

SEE THE IDEA

Default means continue immediately when nothing is ready

  1. 01

    Ready case

    go
    case value := <-ch:

    Receive without waiting

  2. 02

    No ready case

    go
    default:

    Take the fallback immediately

  3. 03

    Blocking alternative

    go
    select without default

    Wait until a case can proceed

Default changes a blocking select into a try operation.

In practice

Use a default case when a skipped operation is part of the contract, such as a best-effort status update. A loop with default can spin continuously when no work is ready. Prefer a blocking select with cancellation or an explicit timing source for a waiting loop.

Watch out

Default does not run after a timeout and does not wait briefly. It is selected immediately when no communication is ready.

Official reference ↗

Work through the exercise

go
package main

// TryRecv returns the next value and true when one is ready,
// or 0 and false without waiting.
func TryRecv(ch <-chan int) (int, bool) {
	return <-ch, true
}

func main() {}
Try it yourself

Trace each value and write down your reasoning. Copy the source into GopherForge or your local Go environment to compile and check it. This web page does not execute your code or send it to a compiler service.

Progress stays in this browser. No account needed.