What are the zero values of Go's types, and which zero values are "usable" versus dangerous?
Question 1MediumGo 1.22 to 1.25
Every variable in Go is initialized to its type's zero value: 0 for numbers, false for bools, "" for strings, and nil for pointers, slices, maps, channels, functions and interfaces. Structs and arrays are zeroed field by field.
Which nil values are safe to use:
- nil slice:
len,cap,rangeandappendall work on it. - nil map: reads,
len,rangeanddeletework. Writing to it panics. - nil channel: sends and receives block forever. Closing it panics. Inside a
selectthis is useful, because it turns a case off. - nil pointer: dereferencing it panics, but you can still call a method with a pointer receiver if the method handles a nil receiver.
var s []int
s = append(s, 1) // fine
var m map[string]int
fmt.Println(m["x"]) // 0, fine
m["x"] = 1 // panic: assignment to entry in nil map
var mu sync.Mutex // zero value is an unlocked mutex, ready to use
var buf bytes.Buffer // zero value is an empty buffer, ready to use
buf.WriteString("hi")
What the interviewer wants to hear: good Go types have a useful zero value (for example sync.Mutex, bytes.Buffer, strings.Builder), so they need no constructor. Also mention that a nil slice and an empty slice behave the same, except under == nil and in JSON encoding (null vs []).
More on Language Fundamentals & Types
- Q2What is the difference between
newandmake? - Q3What does this program print? (iota)
- Q4What are untyped constants? Explain why
const huge = 1 << 100compiles. - Q5What is the difference between a typed and an untyped constant when you assign or compare it?
- Q6Explain variable shadowing. Find the bug in this code.
- Q7What are the rules for
:=redeclaration, and why does this not compile?