JSON encoding and anonymous fields

727 views
Skip to first unread message

DisposaBoy

unread,
Jun 12, 2012, 2:58:13 AM6/12/12
to golan...@googlegroups.com
it's certainly possible and I'm sure it used to support this use-case but that support was removed for go1. the rationale is somewhre. I remember reading so it's either on this group or golang-dev . IIRC John Asmuth forked the older pkg on github thus restoring that functionality

Kyle Lemons

unread,
Jun 12, 2012, 11:25:58 AM6/12/12
to DisposaBoy, golan...@googlegroups.com
XML and JSON had different opinions about how to encode anonymous fields.  Rather than try to normalize on a way to handle them consistently, I believe, the decision was to not handle them in either case in order to leave future freedom to decide upon a proper strategy.

John Asmuth

unread,
Jun 12, 2012, 11:34:14 AM6/12/12
to golan...@googlegroups.com
I didn't restore it - the original functionality used the name of the type for the name of the json object. My version just does it inline.

That is,

type W struct {
    X string
}
type Y struct {
    W
    Z string
}

would get a json object like { "X": "whatever", "Z": "whatever" } with my fork. With the original anonymous field handling, it'd be { "W": { "X": "whatever" }, "Z": "whatever" }.

Joel Webber

unread,
Jun 12, 2012, 3:45:46 PM6/12/12
to John Asmuth, golan...@googlegroups.com
Thanks, all. I presumed it was something like that -- I can definitely see how it gets tricky to decide the right default behavior in this case. We've actually settled on using a different pattern that makes the JSON prettier and easier to switch on, which I've seen come up elsewhere on the group. FWIW, I actually really like it, even though it's a bit non-obvious at first:

type Message struct {
  Type string
  First *FirstSubtype `json:"omitempty"`
  Second *SecondSubtype `json:"omitempty"`
}

type FirstSubtype struct {
  Something string
}

type SecondSubtype struct {
  SomethingElse string
}

This is nice because you end up with slightly clearer JSON and you can switch on the type and dispatch more easily:

switch msg.Type {
  case "first":
    doSomethingWith(msg.First)
  case "second":
    doSomethingElseWith(msg.Second)
Reply all
Reply to author
Forward
0 new messages