Skip to content

Unexpected behavior unmarshaling into interface field #183

Open
@rickbau5

Description

@rickbau5

I am trying to use an interface{} field on a struct to unmarshal into arbitrary struct types using a single field. I'd like to know if the behavior i'm seeing is expected or if there is a different way to accomplish this. I've linked to an example on the Go Playground but will include a few excerpts.

I have a few structs, for example:

type Envelope struct {
	Data interface{} `yaml:"data"`
}

type Foo struct {
	Greeting string `yaml:"greeting"`
}

type Bar struct {
	Farewell string `yaml:"farewell"`
}

And I'm trying to support these configs, as an example:

---
data:
  greeting: "Hello from YAML"`
---
data:
  farewell: "Goodbye from YAML"

I would expect to be able to unmarshal one of those configs using an Envelope with a pointer to Foo or Bar resulting in the fields on Foo or Bar being set to the values in the configuration. Instead, Data on Envelope is a map[string]interface{}.

For example:

var foo Foo
envelope := Envelope{
	Data: &foo,
}

err := yaml.Unmarshal([]byte(yamlPayload), &envelope)
if err != nil {
	panic(err)
}

fmt.Printf("%#v\n", envelope) // main.Envelope{Data:map[string]interface {}{"greeting":"Hello from YAML"}}
fmt.Printf("%#v\n", envelope.Data) // map[string]interface {}{"greeting":"Hello from YAML"}

I would have expected this to print the following:

main.Envelope{Data:(*main.Foo)(0xc000010280)}
&main.Foo{Greeting:"Hello from YAML"}

The unmarshalling doesn't respect the point to the struct set on the interface field and overwrites it with map[string]interface{}

The playground link shows a complete example and includes an example with this behavior from the encdoing/json Unmarshal function, which gives the desired results.
Playground Link

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions