Skip to content

time: Better docs for time.After #70821

@cserban-plenty

Description

@cserban-plenty

Go version

go1.23.1 darwin/arm64

Output of go env in your module/workspace:

Not Needed

What did you do?

package main

import (
	"fmt"
	"time"
)

func main() {
	wait := func() {
		ticker := time.NewTicker(time.Second)
		defer ticker.Stop()

		for {
			select {
			case <-ticker.C:
				fmt.Println("Tick")
			case <-time.After(time.Second * 5):
				fmt.Println("Done")
				return
			}
		}
	}

	wait()
}

What did you see happen?

time.After never gets triggered, for good reasons, it gets reset every iteration when selected. The docs could do better here.

What did you expect to see?

The example in docs looks like:

package main

import (
	"fmt"
	"time"
)

var c chan int

func handle(int) {}

func main() {
	select {
	case m := <-c:
		handle(m)
	case <-time.After(10 * time.Second):
		fmt.Println("timed out")
	}
}

And given that most of the time select is used inside a for loop, one could do so without thinking more about it, which can have side effects because in this case we'd create a new timer each iteration when the case is selected.

I know the docs at some point say that time.After is a shortcut to time.NewTimer(d).C but it also need a caution note that says it has to stay outside of a for loop.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions