-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: encoding/json: iter.Seq marshal support #65873
Comments
How would this be implemented?
is obviously not possible. |
Ok, it's possible with reflection, see #61897 (comment) |
I would love for there to be a general-purpose API to dynamically represent types that is semantically equivalent to a Go slice or map, thus container types like linked lists or b-trees don't need custom For this to happen I would expect:
|
@gophun, the suggested implementation using |
To encode and decode Here's an example implementation: func (s Seq[V]) MarshalJSON() ([]byte, error) {
var buf bytes.Buffer
buf.WriteByte('[')
first := true
for v := range s {
if !first {
buf.WriteByte(',')
}
first = false
bytes, err := json.Marshal(v)
if err != nil {
return nil, err
}
buf.Write(bytes)
}
buf.WriteByte(']')
return buf.Bytes(), nil
}
func (s *Seq[V]) UnmarshalJSON(bytes []byte) error {
var vs []V
if err := json.Unmarshal(bytes, &vs); err != nil {
return err
}
*s = Iter(vs)
return nil
} This implementation allows |
To be an appropriate solution, I would expect the following properties:
|
Iterators as we currently (experimentally) have them (i.e. To unmarshal, we'd need something equivalent to C++'s Output Iterator, then we could use an equivalent to a |
Then again, making Marshal and Unmarshal asymmetric isn't great, either. For example let's look at the types generated by protoc for grpc/protobuf. When I make a request, I would like to be able to pass a Does that mean protoc would need to generate two different versions of each message for sending and receiving? That does not seem desirable. If I just want to forward (part of) an incoming message to another service, I don't want to have to convert it first. |
It is possible in principle to return an But of course the first round of iterators only supports infallible iterators, so any attempt to delay doing the JSON parsing creates the possibility of errors in a place where they cannot be handled. In principle it could call To me this just feels like a natural consequence of not supporting fallible iterators: it isn't appropriate to use the iterator abstraction for anything that can dynamically fail, and JSON parsing can dynamically fail. (I acknowledge that this alternative is also JSON-specific and so fails the goal of being generalizable over multiple serialization formats, but I think the inability to handle errors disqualifies this approach even before considering any formats beyond JSON.) |
Proposal Details
I propose that
json.Marshal
should treatiter.Seq[T]
like[]T
, encoding it as an array. Then we can e.g. write this:and avoid allocating a slice.
The text was updated successfully, but these errors were encountered: