How so? In Go, nil is the zero value for a pointer and is ripe for panic just like null. Zero values do not avoid that problem at all, nor do they intend to.
How so? In Go, nil is the zero value for a pointer and is ripe for panic just like null. Zero values do not avoid that problem at all, nor do they intend to.
Unfortunately, there is no escaping the extra bits. Not a terribly big deal for a large, powerful machine with lots of memory, but might be a big deal over constrained networks. Presumably that is why proto3 tried to save on the amount of data being transferred. It adds up at Google scale. But it did eventually walk back on that idea, making the extra data opt-in.
However, nil slices work just fine when calling append on them, while writing to a nil map in any way will panic.
For the nil slice though what I said remains true: a nil slice is the same thing as an empty slice. Of course reading from or writing to its first element panics, given that it doesn't have any elements. The same would have happened if you had initialized it as `var ns []int = make([]int, 0)` or `ns := []int{}`.
Ironically, just today I read that in the next release they will add some JSON annotation to distinguish nil slices (omitzero): https://tip.golang.org/doc/go1.24
struct {
data uintptr
len int
cap int
}
Which is usable when the underlying memory is set to zero. So its zero value is really an empty slice. Most languages seem to have settled on empty slice, array, etc. as the initialized state just the same. I find it interesting you consider that the worst case.Maps are similar, but have internal data structures that require initialization, thus cannot be reliably used when zeroed. This is probably not so much a performance optimization as convention. You see similar instances in the standard library. For example:
var file os.File
file.Read([]byte{}) // panics; file must be initialized first.Its a performance thing, the map structure requires a heap allocation even with zero elements. This is because the map structure is type generic without being fully monomorphized.
But, that is not the convention. It is well understood that if a struct needs allocations that you must first call a constructor function (e.g. package.NewFoo). It is reasonable to expect that map would stick to the same convention.