The TL;DR here is that if the standard encoding/json
machinery in
Go sees a null
in a JSON field or a nil
pointer in a Go field (of type
*T
), then it will not invoke the UnmarshalJSON()
/ MarshalJSON()
on
your type.
$ go run ./main.go
t1 = main.T{Shift:(*main.Point)(nil)} (nil stays nil, UnmarshalJSON() not invoked)
t2 = main.T{Shift:(*main.Point)(nil)} (see non-nil overwritten, UnmarshalJSON() not invoked)
::: Point{}.UnmarshalJSON() was invoked
t3 = main.T{Shift:(*main.Point)(0x140000a40f0)}; t3.Shift = &main.Point{X:8, Y:15} (see non-nil overwritten, UnmarshalJSON() invoked)
::: Point{}.MarshalJSON() was invoked
JSON(t4) = {"shift":{"x":3,"y":4}} (handle non-nil, MarshalJSON() invoked)
JSON(t5) = {"shift":null} (handle non-nil, MarshalJSON() not invoked)
Playground to give it a spin