5 ms·
> Since encoding/json marshals a nil slice or map as a JSON null How did that make it into the v1 design?
by tibbe 1y ago
> Since encoding/json marshals a nil slice or map as a JSON null
How did that make it into the v1 design?
- rowanseymour 1y agoI had a back and forth with someone who really didn't want to change that behavior and their reasoning was that since you can create and provide an empty map or slice.. having the marshaler do that for you, and then also needing a way to disable that behavior, was unnecessary complexity.
- binary132 1y agohow is a nil map not null? It certainly isn’t a zero-valued map, that would be {}.
- atombender 1y agoThe zero value of a map is indeed nil in Go: This prints true (https://go.dev/play/p/8dXgo8y2KTh https://go.dev/play/p/8dXgo8y2KTh): var m map[string]int println(m == nil)
- binary132 1y agoOk, true!
- materielle 1y agoIt should be marshaled into {} by default, with a opt-out for special use cases. There’s a simple reason: most JavaScript parsers reject null. At least in the slice case.
- tubthumper8 1y agoNot sure what you mean here by "most JavaScript parser rejects null" - did you mean "JSON parsers"? And why would they reject null, which is a valid JSON value? It's more that when building an API that adheres to a specification, whether formal or informal, if the field is supposed to be a JSON array then it should be a JSON array. Not _sometimes_ a JSON array and _sometimes_ null, but always an array. That way clients consuming the JSON output can write code consuming that array without needing to be overly defensive
- rplnt 1y agoWell those are different things, aren't they? Empty slice/map is different from nil. So it makes a lot of sense that nil = null and []string{} = [], and you have an option to use both. That being said, it starts to make less sense if you work with go where the API mostly treats it as equivalent (append, len, []). So that would be my guess how it ended up the way it did. Also, now that nil map is an empty object, shouldn't that extend to every nil struct that doesn't have a custom marshaller? It would be an object if it wasn't nil after all...
- int_19h 1y agoIt is different from nil, but then again a nil map in Go behaves like an empty map when reading from it. If you consider serialization to be "reading", therefore, it makes sense to interpret it accordingly.
- leononame 1y agoThat is not true, though. Reading from a nil map panics, and reading from an empty map does not.
- int_19h 1y agoIt doesn't. E.g. this prints 0: var m map[string]int = nil fmt.Println(m["foo"]) The language spec is also pretty clear on this; https://go.dev/ref/spec#Map_types https://go.dev/ref/spec#Map_types: > A nil map is equivalent to an empty map except that no elements may be added.
- stackedinserter 1y agoWhy shouldn't it be? The nil is null and empty array is an empty array, they are completely different objects.
- maleldil 1y agoNot in Go. Empty slices and empty maps are nil, so it's ambiguous.
- stackedinserter 1y agoNo, empty slices and empty maps in Go are not nil.
- maleldil 1y agoThis is the idiomatic way of declaring empty slices in Go, and it prints true: var slice []string fmt.Println(slice == nil)
- tux3 1y agoThis is indeed a nil slice, and it does have len() == 0, but Go also has a concept of empty slices separate from nil slices The language just has a bad habit of confusing them some of the time, but not consistently, so you can still occasionally get bit by the difference As someone who uses Go a lot, it's just one of those things...
- everybodyknows 1y agoWhether to judge the line below idiomatic, or not, is a question I leave to the authorities -- but it is highly convenient, and prints "false". slice := []string{} fmt.Println(slice == nil)
- deleted 1y ago[deleted]
- stackedinserter 1y ago