Description
I have been playing around with this feature-rich library to see how it operates, but the following puzzled me pretty much and
I dont understand it. It would really help what the underlying pin points are what makes the two examples destinct, wenn encoding and then decoding (which is the problem).
I have the follwing structs:
Example A (with interface)
type B struct {
N int `yaml:"n"`
}
type A struct {
Number int `yaml:"number"
Data Interface `yaml:"data"` // here B gets assigned
}
type Interface interface {}
Example B (Wrapping the interface in a concrete type)
type B struct {
N int `yaml:"n"`
}
type A struct {
Number int `yaml:"number"`
Data Wrapper `yaml:"data"`
}
type Wrapper struct {
Data Interface `yaml:",inline"` // here B gets assigned
}
type Interface interface {}
// Implementing the InterfaceUnmarshaler
func (w Wrapper) UnmarshalYAML(unmarshal func(any) error) error {
return unmarshal(w.Data)
}
// Implementing the InterfaceMarshaler
func (w Wrapper) MarshalYAML() (any, error) {
return w.Data, nil
}
Observations in the Marshal and Unmarshal Loop
-
In Example A I can create struct
var a A{Data: B{}}
and marshal it properly. The unmarshal does not work as
the library throws an error that it cannot assignmap[interface{}]interface{}
toInterface
. -
In Example B I can marshal properly and also the unmarshaling works without any error.
Questions
- In Example A somehow
go-yaml
usesreflect
to iterate on the fields onA
and also it is able to magically marshalData
which is an interface and does not implement UnmarshalYAML. But the unmarshaling does not work, but it works in example B, when it is wrapped in a typeWrapper
which implements theUnmarshalYAML
function.
I don't get why:
go-yaml
cannot figure out in example A that it can unmarshal intoData
? (when it could marshal it?) Why is this asymetric behavior, is it due toreflect
?- In example B, I am just forwarding the interface
Data
to theunmarshal
function which then works for unmarshaling, which makes me wonder why in this case it works?
Thanks a lot for the help. It would be great to make this example into a documentation/example once this issue resolves in something meaningful. =)