var, const, the := short form, zero values, and iota.
Declaring Variables
Go is statically typed — every variable has a type fixed at compile time — but you almost never have to write the type explicitly. The compiler infers it.
Three ways to declare
var x int // 1. var with explicit type, zero-valued (x == 0)
var y = 42 // 2. var with inferred type (y is int)
z := "hello" // 3. short declaration (only inside functions)
The short form := is the everyday tool. The longer var form is mostly for
package-level (outside any function) declarations and zero-value initializations.
Declaring many at once
var (
host string = "localhost"
port int = 8080
)
a, b := 1, 2 // multiple short declarations
a, b = b, a // swap — no temp variable needed
A := rule that surprises people
:= declares at least one new variable. You can mix in existing variables on
the left-hand side, and they're just re-assigned:
If none of the variables on the left are new, := is a compile error.
Unused variables are an error
func main() {
x := 10 // declared but not used → compile error!
}
This is on purpose. Most "unused" variables are bugs (a typo'd reassignment, a
forgotten parameter). Use _ to ignore values you genuinely don't want:
_, err := openFile("config.toml")
Note: unused imports are also a compile error, but unused function arguments and struct fields are not.
Watch out for accidental shadowing
:= inside a block creates a new variable in that block, even if a variable
with the same name exists outside. This is a frequent bug source:
err := load()
if cond {
x, err := compute() // ← inner `err` SHADOWS the outer one
use(x, err)
}
// outer `err` is still whatever load() returned — not what compute() returned!
If you only want to assign, use =, not :=. The go vet tool catches the most
dangerous cases.