3. Variables, types, zero values, constants
3.1 Declaring variables
var count int // zero value: 0
var name string // zero value: ""
var ready bool // zero value: false
var price float64 // zero value: 0.0
x := 42 // short form; type inferred, only inside functions
var y int = 42 // equivalent, explicit
The zero value rule is load-bearing: every declared-but-unassigned
variable in Go gets a well-defined, usable value — 0, "", false,
nil — never garbage memory. A struct zero value is every field
zeroed recursively. This eliminates an entire class of "uninitialized
variable" bugs common in C.
3.2 Basic types
bool, string, int/int8/int16/int32/int64,
uint/uint8(byte)/uint16/uint32/uint64, float32/float64,
complex64/complex128, rune (alias for int32, a Unicode code point).
int and uint are platform-width (64-bit on virtually everything you'll
target today) — use them for general-purpose counting, and use the sized
variants only when the width matters (wire formats, hashing, bit twiddling).
3.3 Constants and iota
Constants are untyped until used, which lets const Pi = 3.14159 work as a
float64 in one expression and (if it fit) an int in another. iota
generates enumerations without hand-numbering:
type Unit int
const (
Byte Unit = 1 << (10 * iota) // iota = 0 -> 1
KB // iota = 1 -> 1024
MB // iota = 2 -> 1024*1024
GB // iota = 3 -> 1024*1024*1024
)
func (u Unit) String() string {
switch u {
case KB:
return "KB"
case MB:
return "MB"
case GB:
return "GB"
default:
return "B"
}
}
3.4 Type conversion is always explicit
var i int = 42
var f float64 = float64(i) // no implicit int->float64
var u uint = uint(f) // no implicit float64->uint either
There is no silent widening or narrowing anywhere in Go. If a bug turns an
int32 into an int64 unexpectedly, it's because you wrote the
conversion, not because the compiler inferred one.
3.5 Real-world example
The Unit + iota pattern above is the backbone of Day 2 in the 90-day
plan's "network unit converter" exercise — the same trick scales to HTTP
status classes, log levels (DEBUG/INFO/WARN/ERROR), and protocol
opcodes, anywhere you need a small closed set of named integers with a
String() method for readable logs.