関連記事
GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ
概要
以下、自分用のメモです。前回の続きです。
Go 1.25 のドラフトリリースノートは以下。
上記を見ると、Go 1.25 で go vet コマンドに sync.WaitGroup 向けのチェックが追加されるみたいですね。
waitgroup, which reports misplaced calls to sync.WaitGroup.Add;
ってあるので、sync.WaitGroupの間違った使い方があった場合に警告してくれるとのこと。
では、どんなパターンのときに警告してくれるとかというと
waitgroup package - golang.org/x/tools/go/analysis/passes/waitgroup - Go Packages
にあるみたいに
// WRONG var wg sync.WaitGroup go func() { wg.Add(1) // "WaitGroup.Add called from inside new goroutine" defer wg.Done() ... }() wg.Wait() // (may return prematurely before new goroutine starts)
って感じで、ゴルーチン内で wg.Add() してしまっているパターンのみみたいですね。
このパターン、コンパイルは当然通るし、実行も出来るのですが正しく待ち合わせが出来ない可能性が発生します。(Waitに入る前に動くことが出来たゴルーチンがいた場合は、その数だけ待機してくれるけど、全ゴルーチン分がWait前にAdd(1)を呼び出せるかどうかは不定。普通は速攻でWaitが呼ばれるので、Addしているものが一つも存在せずに即終了してしまう)
一応、ちゃんと警告されるか試してみました。
試してみた
go version
$ go version go version go1.25rc1 linux/arm64
main.go
package main import ( "fmt" "sync" ) func main() { const ( NumWorkers = 3 ) var ( wg sync.WaitGroup ) for range NumWorkers { // 本来はゴルーチン外でAddしないと駄目 go func() { wg.Add(1) // 間違えてる defer wg.Done() fmt.Println("hello world") }() } wg.Wait() }
go vet
go vet するとちゃんと警告でますね。
$ go vet . # app # [app] ./main.go:18:10: WaitGroup.Add called from inside new goroutine
main.go (2)
正しい形に直して
package main import ( "fmt" "sync" ) func main() { const ( NumWorkers = 3 ) var ( wg sync.WaitGroup ) for range NumWorkers { wg.Add(1) go func() { defer wg.Done() fmt.Println("hello world") }() } wg.Wait() }
vetすると警告は消えました。
$ go vet .
参考情報
Goのおすすめ書籍
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。





