Go

What does this print? (nil vs empty slices and maps in JSON)

Question 455MediumGo 1.22 to 1.25
type Resp struct {
	Items []int          `json:"items"`
	Meta  map[string]int `json:"meta"`
	Ptr   *int           `json:"ptr"`
}

var a []int
b := []int{}
x, _ := json.Marshal(Resp{Items: a})
y, _ := json.Marshal(Resp{Items: b, Meta: map[string]int{}})
fmt.Println(string(x))
fmt.Println(string(y))

var r Resp
json.Unmarshal([]byte(`{"items":null}`), &r)
fmt.Println(r.Items == nil)

Output:

{"items":null,"meta":null,"ptr":null}
{"items":[],"meta":{},"ptr":null}
true

A nil slice/map marshals to null; an empty one to []/{}. Frontend clients doing resp.items.length crash on null, so APIs typically initialize slices (make([]T, 0)) before encoding. On decode, JSON null leaves the slice nil (and for non-pointer scalar fields, null is a no-op, leaving the previous value).

Also: []byte marshals as a base64 string, not an array of numbers — a common surprise.

More on Standard Library, HTTP & Systems Design in Go

All 35 Standard Library, HTTP & Systems Design in Go questions