WaitGroup.Go() (new in Go 1.25)

This is an improvement many of you will love. It is a usability enhancement along the lines of testing’s b.Loop() that did away with a clumsy loop condition (and made benchmarking more efficient) in Go 1.24.

I'm talking about WaitGroup.Go(). Starting with Go 1.25, you no longer need to call Add(1) for each goroutine spawned inside a WaitGroup and hope that there's no mismatch with the number of calls to Done().

With Go 1.25, using a WaitGroup is as easy as:

var wg sync.WaitGroup

for i := 0; i < 3; i++ {
	wg.Go(func() {
    // do something 
	})
}

wg.Wait()

(Playground link)

How is Go() implemented? This is easy to find out, and that's one of the many bits that I love about Go: In the documentation of a Go package on pkg.go.dev, you can click on the title of any identifier (function, type, etc.) to open its source code in Go's official repository. If you drill down on the Go() method, you'll discover that the implementation of WaitGroup.Go() is refreshingly simple; it's just a thin wrapper over the “old” style:

func (wg *WaitGroup) Go(f func()) {
	wg.Add(1)
	go func() {
		defer wg.Done()
		f()
	}()
}

Go() simply does the Add()/Done() bookkeeping under the hood for you. Neat!