This isn’t very specific to go. A lot of RISC ISAs have a zero register defined for reads but something different for writes. Consider a typical RISC instruction. In a 32-bit encoding, 5 bits of this are encoding each operand (with 32 registers). Any non-store instruction has a 5-bit destination so if you allow the zero register as a destination (or as the base address for stores) then you are using 1/32 of your encoding space to encode nops. For comparison, that’s the same amount of the encoding space that AArch64 uses for all load instructions, in all of their complex addressing modes.
The common alternatives are:
It’s also fairly common to retrofit something like this to existing architectures after you run low on encoding space, because no sane compiler generates any no-op that isn’t the canonical no-op. Generally, finding a spare register for the destination of a null check is easy: it’s a register that is live for only the instruction that generates it and so can be the same register as the next instruction uses as its target in the common case. Just plugging in the one-instruction live range to a simple register allocator generally gives good results.