Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems with unmarshalling of structs with interface fields #261

Closed
giggsoff opened this issue May 23, 2020 · 7 comments
Closed

Problems with unmarshalling of structs with interface fields #261

giggsoff opened this issue May 23, 2020 · 7 comments

Comments

@giggsoff
Copy link

Hi! I try to use Msgpack to marshal structs with interface fields. During the unmarshal, the library panics. Here is an example: https://gist.github.com/giggsoff/b261040fb97f9ff8f81145a5ed440ec3
And I got:

2020/05/23 20:15:20 Before marshalling:  &{123}
panic: reflect.Set: value of type map[string]interface {} is not assignable to type main.interfaceAlias

goroutine 1 [running]:
reflect.Value.assignTo(0x4df9a0, 0xc000098420, 0x15, 0x4fe6dc, 0xb, 0x4e1ac0, 0xc000096530, 0xc000098420, 0x0, 0x0)
        /snap/go/5759/src/reflect/value.go:2403 +0x426
reflect.Value.Set(0x4e1ac0, 0xc000096530, 0x194, 0x4df9a0, 0xc000098420, 0x15)
        /snap/go/5759/src/reflect/value.go:1532 +0xbd
github.com/vmihailenco/msgpack/v4.(*Decoder).interfaceValue(0xc0000ce000, 0x4e1ac0, 0xc000096530, 0x194, 0x4e1ac0, 0xc000096530)
        /home/giggsoff/go/pkg/mod/github.com/vmihailenco/msgpack/v4@v4.3.11/decode_value.go:247 +0x150
github.com/vmihailenco/msgpack/v4.decodeInterfaceValue(0xc0000ce000, 0x4e1ac0, 0xc000096530, 0x194, 0x1, 0x1)
        /home/giggsoff/go/pkg/mod/github.com/vmihailenco/msgpack/v4@v4.3.11/decode_value.go:219 +0x1ef
github.com/vmihailenco/msgpack/v4.(*field).DecodeValue(0xc0000bc0c0, 0xc0000ce000, 0x4e2b60, 0xc000096530, 0x199, 0xc000096430, 0x4e7680)
        /home/giggsoff/go/pkg/mod/github.com/vmihailenco/msgpack/v4@v4.3.11/types.go:110 +0x9b
github.com/vmihailenco/msgpack/v4.decodeStructValue(0xc0000ce000, 0x4e2b60, 0xc000096530, 0x199, 0x4e2b60, 0x7f27962e50c8)
        /home/giggsoff/go/pkg/mod/github.com/vmihailenco/msgpack/v4@v4.3.11/decode_map.go:333 +0x462
github.com/vmihailenco/msgpack/v4.(*Decoder).DecodeValue(0xc0000ce000, 0x4e2b60, 0xc000096530, 0x199, 0xc000096530, 0x199)
        /home/giggsoff/go/pkg/mod/github.com/vmihailenco/msgpack/v4@v4.3.11/decode.go:280 +0x8c
github.com/vmihailenco/msgpack/v4.(*Decoder).Decode(0xc0000ce000, 0x4d2ce0, 0xc000096530, 0xc000093ed8, 0x40beb8)
        /home/giggsoff/go/pkg/mod/github.com/vmihailenco/msgpack/v4@v4.3.11/decode.go:259 +0x171
github.com/vmihailenco/msgpack/v4.Unmarshal(0xc0000cc040, 0xe, 0x40, 0x4d2ce0, 0xc000096530, 0x0, 0x0)
        /home/giggsoff/go/pkg/mod/github.com/vmihailenco/msgpack/v4@v4.3.11/decode.go:51 +0xcb
main.main()
        /home/giggsoff/go/src/msgpackTest/customIf/main.go:40 +0x1c4
exit status 2

When I initialize struct before unmarshalling to it here https://gist.github.com/giggsoff/65606a03d84288000f0cd01684eb1b48
I got wrong result (expected result is the same lines):

2020/05/23 20:43:32 Before marshalling:  &{123}
2020/05/23 20:43:32 After marshalling:  &{0 456}

And I cannot use library in app lf-edge/adam#32

@dolmen
Copy link

dolmen commented Jun 24, 2020

Here is the code on the Go playground: https://play.golang.org/p/2RpoOtWkhYi

@dolmen
Copy link

dolmen commented Jun 24, 2020

This is not an issue about msgpack.

This is an issue about your expectation that it would be possible to deserialize into an interface.
No serialization library can do that. Libraries need concrete types as serialization targets. They can't magically find which concrete type they must instantiate that implement that interface.

I have converted your example to use encoding/json to show you that it can't do better. See on the Go playground: https://play.golang.org/p/JlvyOINsi5e

@vmihailenco
Copy link
Owner

I believe this is not working in v5

@tmm1
Copy link
Contributor

tmm1 commented Mar 9, 2021

No serialization library can do that. Libraries need concrete types as serialization targets. They can't magically find which concrete type they must instantiate that implement that interface.

This is not strictly true. The gob serializer can encode the concrete type underlying an interface and unmarshal on the other side.

https://github.com/golang/go/blob/b6def6a34e049d5d2cc9225d991c4b84427467ec/src/encoding/gob/encode.go#L380-L384

@tmm1
Copy link
Contributor

tmm1 commented May 9, 2021

I believe this is now working in v5

@vmihailenco Can you reopen this issue because the behavior is still the same with v5

@dolmen
Copy link

dolmen commented May 19, 2021

This is not strictly true. The gob serializer can encode the concrete type underlying an interface and unmarshal on the other side.

The difference is that gob is a pure go serialization format. Instead msgpack is designed for interoperability and implementations for multiple programming languages exist. You are asking for a change in the serialization format that would break many existing use cases.

@tmm1
Copy link
Contributor

tmm1 commented May 19, 2021

Here's an example of how to use CustomDecoder to solve this issue: https://play.golang.org/p/lbG2ys92Oik

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants