What does go vet catch? What does it report for the code below?
Question 431MediumGo 1.22 to 1.25
package main
import (
"context"
"fmt"
"sync"
"time"
)
type Counter struct {
mu sync.Mutex
n int
}
func (c Counter) Inc() { c.mu.Lock(); c.n++; c.mu.Unlock() } // (1)
func main() {
ctx, _ := context.WithTimeout(context.Background(), time.Second) // (2)
_ = ctx
fmt.Printf("%d items\n", "three") // (3)
}
go vet reports three problems:
- copylocks:
Inc passes lock by value. The value receiver copies the mutex, and the increment is lost. Usefunc (c *Counter). - lostcancel: the cancel function is discarded, so the context and its timer leak until the timeout fires.
- printf:
%dwith a string argument.
Other default analyzers include structtag (malformed json:"x,omitempty" tags), unreachable, unusedresult, atomic (x = atomic.AddInt64(&x, 1)), httpresponse (using resp before checking err), tests (malformed Test/Example names), stdversion (1.23: API newer than the go line), waitgroup (1.25: wg.Add inside the goroutine), and buildtag.
go test automatically runs a high-confidence subset (atomic, bool, buildtags, directive, errorsas, ifaceassert, nilfunc, printf, stringintconv, tests). Vet's analyzers are chosen to have very few false positives, so it belongs in CI as a hard gate. shadow is not included by default.
More on Modules, Packages & Tooling
- Q429How do you inject a version string at build time with -ldflags? What does this program print?
- Q430What build metadata does a Go binary carry, and how do you make builds reproducible?
- Q432How do staticcheck and golangci-lint differ from go vet? How would you set up linting for a team?
- Q433How does //go:embed work? Show the three target types.
- Q434What are the gotchas of go:embed patterns? Why is my .env or _redirects file missing?
- Q435What does this print? Explain Go's package initialization order.