0

I have constructed a small example of what I am trying to do:

type Service interface {
    Transform()
}

type XYZ struct {
    ID string `json:"id"`
}

func (s XYZ) Transform() {}

func main() {
    x := "could be anything"
    msg := []byte(`{"id": "123"}`)

    var msgS Service

    switch x {
    case "could be anything":
        msgS = XYZ{}
        break
    case "could be something else":
        // another type that implements Transform()
        break
    }

    err := json.Unmarshal(msg, &msgS)

    if err != nil {
        fmt.Println(err)
    }

    // msgS.Transform()
}

Go Playground

This returns an error:

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

Essentially, I need to be flexible with whatever x might hold, hence the switch. If I instantitate msgSto the actual type that implements Transform(), all works as expected.

I realise I might need to reconsider my whole implementation - Any ideas would be welcome!

joe
  • 305
  • 1
  • 4
  • 9
  • 1
    I don't think you can unmarshal into an interface, [check this thread](https://stackoverflow.com/questions/35583735/unmarshaling-into-an-interface-and-then-performing-type-assertion). – Anurag Kumar Nov 14 '22 at 18:53
  • 3
    Switch the ampersand, i.e. `msgS = &XYZ{}` and then `json.Unmarshal(msg, msgS)` https://go.dev/play/p/xQMuL_4_PHm – mkopriva Nov 14 '22 at 18:54

1 Answers1

2

You should unmarshal to the concrete type and then you can assign the result to the interface type.

A simple example:

var service Service
var err error

switch x {
    case "something":
        var something Something // this implements Service
        err = json.Unmarshal(data, &something)
        service = something
    case "something else":
        var somethingElse SomethingElse // this implements Service
        err = json.Unsmarshal(data, &somethingElse)
        service = somethingElse
    // etc...
}

if err != nil {
    // handle error (here or inside of each case if you need/want to)
}

// use service as needed here
Lucas Gabriel Sánchez
  • 40,116
  • 20
  • 56
  • 83