Unmarshal json to reflected struct

Viewed 5878

Is it possible to unmarshal JSON into a struct made from reflection without hardcoding the original type?

package main

import (
  "fmt"
  "encoding/json"
  "reflect"
)

type Employee struct {
  Firstname string     `json:"firstname"`
}

func main() {
  //Original struct
  orig := new(Employee)

  t := reflect.TypeOf(orig)
  v := reflect.New(t.Elem())

  //Reflected struct
  new := v.Elem().Interface().(Employee)

  // Unmarshal to reflected struct
  json.Unmarshal([]byte("{\"firstname\": \"bender\"}"), &new)

  fmt.Printf("%+v\n", new)
}

I used a cast to Employee in this example. But what if i don't know the type?

When i just use v for the unmarhaling the struct will be zeroed.

json.Unmarshal([]byte("{\"firstname\": \"bender\"}"), v)

When I omit the cast I get a map. which is understandable

json.Unmarshal([]byte("{\"firstname\": \"bender\"}"), v.Elem().Interface())
3 Answers

// https://github.com/xiaojun207/go-base-utils/blob/master/utils/Clone.go
func NewInterface(typ reflect.Type, data []byte) interface{} {
    if typ.Kind() == reflect.Ptr {
        typ = typ.Elem()
        dst := reflect.New(typ).Elem()
        json.Unmarshal(data, dst.Addr().Interface())
        return dst.Addr().Interface()
    }else {
        dst := reflect.New(typ).Elem()
        json.Unmarshal(data, dst.Addr().Interface())
        return dst.Interface()
    }
}

type Employee struct {
    Firstname string     `json:"firstname"`
}

func main() {
    data := "{\"firstName\": \"John\"}"
    obj := NewInterface(reflect.TypeOf(Employee{}), []byte(data))
    fmt.Println("Employee:", obj)
}
Related