Gert Cuykens
Gert Cuykens

Reputation: 7175

How to store different structs in a interface for json

http://play.golang.org/p/JJnU5ag234

I can only make vA work directly, if I want to use my vI to store A or B in it depending on the json I expect, I get

json: cannot unmarshal object into Go value of type main.TA

package main

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

type T interface {
    Printer()
}

type A struct{ JA string }

func (t A) Printer() { fmt.Print("A") }

type B struct{ JB string }

func (t B) Printer() { fmt.Print("B") }

var vA []A
var vB []B
var vI []T

func main() {
    // vA = []A{A{}}
    // vI = []T{B{}}
    vI = []T{A{}}
    get()
}

func get() {

    dec := json.NewDecoder(strings.NewReader("[{\"JA\":\"OK\"}]"))
    if err := dec.Decode(&vI); err != nil {
        fmt.Print(err)
    }

    for _, v := range vI {
        v.Printer()
    }

}

Upvotes: 0

Views: 59

Answers (1)

David
David

Reputation: 444

Since you expect the decoder to fill the fields of a struct, you have to use pointers. Define methods of the interface on the pointer of the type like this: http://play.golang.org/p/WUMt9Ok9Xp

package main

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

type T interface {
    Printer()
}

type A struct {
    JA string
}

func (a *A) Printer() {
    fmt.Printf("A: %v\n", a.JA)
}

type B struct {
    JB string
}

func (b *B) Printer() {
    fmt.Printf("B: %v\n", b.JB)
}

func main() {
    vI := []T{&A{}, &B{}}
    dec := json.NewDecoder(strings.NewReader("[{\"JA\":\"OKA\"}, {\"JB\":\"OKB\"}]"))
    if err := dec.Decode(&vI); err != nil {
        fmt.Print(err)
    }
    for _, v := range vI {
        v.Printer()
    }
}

Upvotes: 2

Related Questions