When to use zero values
Fast recall
Quick revision
Core answer
sync.Mutex, or a buffer with no data. Explicit initialization is needed when zero is not a valid business state or when internal maps and channels must be allocated. A constructor can establish those invariants, while a useful zero value keeps simple types easier to use.Give a selection rule for zero values, show a practical example, and explain when explicit initialization or a constructor is clearer.
Saying “it depends” without naming the condition that changes the choice.
State the default choice and the specific reason to move away from it.
Interview-ready guide
Interview answer
Rely on the zero value when it already represents a valid starting state, such as an empty counter, an unlocked
sync.Mutex, or a buffer with no data. Choose it because the behaviour is part of the requirement, not simply because the syntax is available.For example: the declarations are immediately readable without manual initialization. A nil slice can be read, ranged over, and appended to, while writing to a nil map panics until
makeinitializes it. This small case shows the reason for the choice directly.Explicit initialization is needed when zero is not a valid business state or when internal maps and channels must be allocated. A constructor can establish those invariants, while a useful zero value keeps simple types easier to use. The two choices solve related problems but communicate different guarantees.
Rely on the zero value when it already represents a valid starting state, such as an empty counter, an unlocked
sync.Mutex, or a buffer with no data. Otherwise, use explicit initialization or a constructor when it keeps the code simpler.
When to use zero values
Direct Answer
Rely on the zero value when it already represents a valid starting state, such as an empty counter, an unlocked sync.Mutex, or a buffer with no data. Explicit initialization is needed when zero is not a valid business state or when internal maps and channels must be allocated. A constructor can establish those invariants, while a useful zero value keeps simple types easier to use.
Deep Dive & Architecture
For an unexpected zero or nil panic, identify whether the value was never assigned, deliberately reset, or missing from decoded input.
Then check the exact operation that requires initialization.
Rely on the zero value when it already represents a valid starting state, such as an empty counter, an unlocked sync.Mutex, or a buffer with no data. Explicit initialization is needed when zero is not a valid business state or when internal maps and channels must be allocated. A constructor can establish those invariants, while a useful zero value keeps simple types easier to use.
A common mistake is assuming every nil value behaves like an empty initialized value. Reading a missing key from a nil map is safe, but writing to that map panics; appending to a nil slice is safe. Know the zero value of each field, initialize maps and channels before use, and model optional business data with an explicit presence flag or pointer when zero is meaningful.
Code Example
var count int // 0
var ready bool // false
var name string // ""
var items []string // nil, append works
var users map[string]int // nil, writes panic
Common Mistakes & Pitfalls
Saying “it depends” without naming the condition that changes the choice.
Check your understanding
Answer these without looking back at the article.
- What are zero values in Go, and how do they work?
- How do zero values compare with explicit initialization or a constructor in Go?
- What common mistakes should you avoid with zero values in Go?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.