2

Suppose I have a Go struct, complete with JSON tags:

type Person struct {
    Name    string   `json:"name"`
    Age     int      `json:"age,omitifempty"`
    Flags   []string `json:"-"`
}

p := Person{ Name: "Bob", Age: 36, Flags: []string{"employed","father"} }

Now I want to convert this to a generic map[string]interface{}, such as I might receive from a REST API via JSON:

p2 := map[string]interface{}{
    "name": "Bob",
    "age": 36,
}

I have devised the following function to accomplish this using the json package. But the intermediate step of a JSON string seems unnecessary and wasteful.

func ConvertJSONObject(input, output interface{}) error {
    encoded, err := json.Marshal(input)
    if err != nil {
        return err
    }
    return json.Unmarshal(encoded, output)
}

Now I can do this:

var p2 map[string]interface{}
ConvertJSONObject(p, &p2)

As an added bonus, the same function works in reverse, to turn a map[string]interface{} into a populated struct:

var p Person
ConvertJSONObject(p2, &p)

Is there a simpler solution, which honors tags in the roughly the same way the json package does?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
  • You can also directly marshal the struct without converting to map[string]interface{} before. The same applies for unmarshaling. I don't quite understand why you would want/need to take the detour over the map – tike Dec 19 '15 at 20:51
  • @tike: Yes, if I have JSON-formatted data. I don't. This question is about not having to use JSON as the intermediate step. – Jonathan Hall Dec 19 '15 at 20:52
  • So why do you need to convert the struct to map in the first place? – tike Dec 19 '15 at 20:54
  • I need to interface with an API that expects an arbitrary structure, but I don't want to have to pass `map[string]interface{}` all over the place in my code. – Jonathan Hall Dec 19 '15 at 20:56
  • Does API mean a function in some library you use, which accepts only map[string]interface{} as argument? Just to be clear :-) – tike Dec 19 '15 at 20:58
  • @tike: Basically. But don't get hung up on that detail. I've actually been using this pattern in a number of projects with slightly different APIs and needs , and just want to find a better solution. – Jonathan Hall Dec 19 '15 at 20:59
  • I know I can just re-implement what the `json` package does with reflection to read the tags... and that's probably what I will do. But I was hoping for something simpler, which wouldn't require my own, hairy utility functions – Jonathan Hall Dec 19 '15 at 21:02
  • https://github.com/mitchellh/mapstructure ? – elithrar Dec 19 '15 at 21:05
  • @elithrar: That looks promising. Thanks! – Jonathan Hall Dec 19 '15 at 21:06
  • @CodingPickle: That's similar, but seems to ignore tags, which I would consider a vital part of my question. – Jonathan Hall Dec 20 '15 at 10:15

0 Answers0