Go: workaround to json.Unmarshal being incapable of deserialising into custom interface type

in #go7 years ago

You may have noticed that json.Unmarshal always refuses to deserialise JSON into a custom interface type. For example, given a custom interface:

type Fruit interface {
    Name() string
}

... And to deserialise a Lemon:

type Lemon struct {
    KindOfLemon string
}
func (le Lemon) Name() string {
    return le.KindOfLemon
}

...But due to certain circumstances, the code cannot touch Lemon directly, all you have is a Fruit:

var deserialisedLime Fruit = Lemon{}
fmt.Println(json.Unmarshal(serialsedLime, &deserialisedLime))

Unmarshal function will complain that it "cannot unmarshal object into Go value of type INTERFACE-NAME".

Don't worry - the statement is simply false, the JSON package is in fact perfectly capable of doing it, just use a little reflection trick:

var limeReflectValue = reflect.New(reflect.TypeOf(Lemon{}))
var limeIface interface{} = limeReflectValue.Interface()
fmt.Println(json.Unmarshal(serialsedLime, &limeIface))

// Confirmation
var getLimeBack Fruit = limeIface.(Fruit)
fmt.Println(getLimeBack.Name()) // lime confirmed
}

Enjoy!