Knaph

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.go
hello %!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.go
main.go:7:20: fmt.Printf format %d has arg name of wrong type string

A 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 as json"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.

Sign in to track your progress through this course.

Ask an AI

Open a ready-made prompt in ChatGPT or Claude — just press Enter.

SummarizeChatGPTClaude
Ask me questionsChatGPTClaude
Let's learn togetherChatGPTClaude