go vet
Go's compiler is stricter than most — an unused import or unused local variable is a hard error, not a warning — so a whole category of linting doesn't exist here. What's left is the interesting part: code that is perfectly valid Go and almost certainly not what you meant.
package main
import "fmt"
func main() {
name := "Haleh"
fmt.Printf("hello %d\n", name)
}go run main.gohello %!d(string=Haleh)It compiled, it ran, and it printed nonsense. The compiler had no grounds to object: Printf takes ...any, so passing a string is fine as far as the type system is concerned. The mismatch is between the contents of a string literal (%d) and an argument — a relationship only a tool that understands Printf can check.
That tool ships with Go:
go vet main.gomain.go:7:20: fmt.Printf format %d has arg name of wrong type stringA sample of what its analyzers cover:
- format strings that don't match their arguments
- struct tags that don't parse — a
json:"name"typo'd asjson"name"silently does nothing - unreachable code
- a lock copied by value instead of by pointer
The list is deliberately short. Vet only reports what is almost certainly a mistake, never merely suspicious — false positives train you to ignore a tool, and an ignored tool is worse than none. That restraint earned it a privileged position: go test runs a subset of vet automatically, so the file above fails the test run without anyone asking for it.
Like go fmt, the ./... form needs a go.mod. Until you have one, name files directly.