Skip to content

Instantly share code, notes, and snippets.

@Northern-Lights
Created March 15, 2019 23:00
Show Gist options
  • Save Northern-Lights/b2d01533b5a88389bab40a1053832445 to your computer and use it in GitHub Desktop.
Save Northern-Lights/b2d01533b5a88389bab40a1053832445 to your computer and use it in GitHub Desktop.
JSON unmarshaling when a struct contains an interface field
// https://play.golang.org/p/l_GmjX31XbM
package main
import (
"encoding/json"
"fmt"
)
// Main has a Field2 whose type we don't know at the time of unmarshaling. We
// will demonstrate a very simple case of custom unmarshaling when the interface
// type is a base type (int or string.) If you have a more complex type, then
// you may have to use more maps and additional logic to discover what concrete
// type is held by the interface
type Main struct {
Field1 string `json:"field1"`
Field2 Interface `json:"field2"`
}
type Interface interface {
Print()
}
type Impl1 int
func (i Impl1) Print() {
fmt.Println(i)
}
type Impl2 string
func (i Impl2) Print() {
fmt.Println(i)
}
func (m *Main) UnmarshalJSON(data []byte) (err error) {
temp := make(map[string]interface{}, 2)
err = json.Unmarshal(data, &temp)
if err != nil {
return
}
m.Field1 = temp["field1"].(string)
switch val := temp["field2"].(type) {
case string:
m.Field2 = Impl2(val)
case float64:
m.Field2 = Impl1(int(val))
default:
err = fmt.Errorf("type %T not supported", val)
}
return
}
func main() {
var (
src = Main{
Field1: "field",
Field2: Impl1(1),
}
dst Main
)
fmt.Println("src")
fmt.Println(src)
ser, err := json.Marshal(&src)
if err != nil {
panic(err)
}
fmt.Println(string(ser))
err = json.Unmarshal(ser, &dst)
if err != nil {
panic(err)
}
fmt.Println(dst)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment