points by thayne 3 days ago | 0 comments
In go, the Marshall and unmarshal functions take `any` for the source or destination. If you use a value of a type that doesn't support marshaling or unmarshalling (say because it contains an unserializable type like a channel, function pointer, etc) then you get a runtime error. Whereas in rust, Haskell, scala, etc. you can get a compile time error if you try to use a type that doesn't support serialization.
[–] hnlmorg 3 days ago
[–] thayne 2 days ago
> You don’t get runtime errors for marshalling pointers to JSON
https://pkg.go.dev/encoding/json/v2#Marshal says otherwise:
> The Go map key must encode as a JSON string, otherwise this results in a SemanticError
> All other Go types (e.g., complex numbers, channels, and functions) have no default representation and result in a SemanticError.
v1 has the same constraints.
[–] hnlmorg 2 days ago
> A Go pointer is encoded as a JSON null if nil, otherwise it is the recursively JSON-encoded representation of the underlying value.
The doc you linked to literally proves me right.
[–] thayne 2 days ago
That just shows there are pointer values that can be marshaled, not that all such values won't error. If you have a non-nil pointer that points to an object that transitively contains one of the unsupported types, you will get an error.
[–] hnlmorg 2 days ago
I read that differently. If you have a non-nil pointer then you get the address of the pointer irrespective of what that pointer points too.
[–] thayne 1 day ago
I'm not sure how you are getting that from "otherwise it is the recursively JSON-encoded representation of the underlying value", but here is a playground example, where using a non-nil pointer to a channel produces an error:
https://go.dev/play/p/JXYuGUQ0TLQ
I think the same is true for channels too but I’m not near a computer to check.
I’ve abused the v1 API heavily* and haven’t found anything it couldn’t marshal. Though I’m yet to apply the same “fuzzing” (for lack of a better term) to v2.
* the v1 JSON marshaller underpins some core functionality in my alternative $SHELL. So I’ve thrown a lot of exotic type structures (by Gos standards at least) at it.