Variable shadowing
Avoid reusing names across nested scopes when `:=` can silently change which value later code observes.
Canonical guidance
- keep scopes narrow and names distinct
- be cautious with
:=when an outer variable already exists - prefer
=when reusing an existing binding is intended
Use when
- error-heavy control flow
- nested
ifblocks - loops with temporary variables
Avoid
- shadowing
errand then reading the outererrlater - reusing short names across distant nested scopes
- large functions where scope boundaries are hard to see
Preferred pattern
f, err := os.Open(name)
if err != nil {
return err
}
defer f.Close()
_, err = io.Copy(dst, f)
if err != nil {
return err
}
Anti-pattern
- mixing outer and inner
errvariables so later checks inspect the wrong one
Explanation: This anti-pattern is tempting because short declarations are convenient, but one extra := can quietly change which variable later code sees.
Why
- shadowing creates bugs that still compile and often still look reasonable in review
Related pages
Sources
- cmd/vet - Go Team
- Unintended variable shadowing (#1) - Teiva Harsanyi