Skip to content

proposal: time: make an uninitialized Timer usable #12721

@cespare

Description

@cespare

Alternatively, add a new function to package time:

// NewStoppedTimer returns a new Timer that never fires unless it is Reset.
func NewStoppedTimer() *Timer

It is common to reuse a timer via Reset several times (usually in a loop); often in these scenarios there's no initial value needed for the timer. It would be nice to be able to do this:

var t time.Timer
for {
    // ...
    t.Reset(x)
    // ...
}

but today any use of a timer that isn't created using NewTimer (or AfterFunc) panics.

Given #11513, almost any "obvious" way of accomplishing this is incorrect:

t := time.NewTimer(0)
for {
    t.Reset(5 * time.Minute)
    <-t.C // might fire immediately, or after 5 minutes
}
t := time.NewTimer(0)
t.Stop()
for {
    t.Reset(5 * time.Minute)
    <-t.C // might fire immediately, or after 5 minutes
}

You need to do something like this instead:

t := time.NewTimer(0)
<-t.C
for {
  t.Reset(5 * time.Minute)
  <-t.C // will not fire immediately
}

but it's unlikely that most people will know that something like this is required, because the bugs in the above versions can be hard to notice.

Compared with t := time.NewTimer(0); <-t.C, either var t time.Timer or time.NewStoppedTimer() are clearer, and the former doesn't even require expanding the time API.

(Note: edited to remove overly-complex workaround.)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions