Hmmmmm, I looked a bit at the code. ISTM that if you implement
BinaryMarshaler/Unmarshaler (or GobEncoder/Decoder), the values are sent as
a []byte, not an interface, so the concrete type information is lost. You
can kind of circumvent this, by instead passing the values as interface{}:
https://play.golang.org/p/n5oxq9g2Q-9 -- As you can see, gob still uses the
methods, but because you more specifically say that it should en/decode
interfaces, it's passing the type-info along too. This will require that
you do your own type-assertions after decoding, but maybe that's acceptable?

The panic, I think, comes from the fact that you pass a *Duck, which then
gets dereferenced, pointing at a nil Duck. Even a nil-Duck *does* have a
DecodeBinary method though, so gob thinks it should use that. It then
type-asserts to BinaryDecoder, which panics, because it's a nil-interface,
just like this example: https://play.golang.org/p/EEwOt0FQunh. Arguably,
the language should allow this (returning nil from the type-assertion), but
either way, it won't help you, because it would panic when calling the
method anyway. So, in a way, gob behaves correctly. It says that if the
value you decode into implements BinaryUnmarshaler, it will call it's
UnmarshalBinary method. And the BinaryUnmarshaler you pass will panic if
you actually call that method. It's still not a great failure mode.

I hope this kinda helps. Or that someone can give a more authoritative
answer :)

On Thu, Aug 15, 2019 at 11:54 AM Axel Wagner <axel.wagner...@googlemail.com>
wrote:

> On Thu, Aug 15, 2019 at 11:14 AM Jochen Voss <jochen.v...@gmail.com>
> wrote:
>
>> You are right.  But the type is somehow represented by some index or so,
>> instead of the name? Since the type needs to be registered using
>> gob.Register() beforehand, this seems not totally impossible to me.
>>
>
> `Register` only gets the type-name though. It somehow would have to
> reproducibly map from type-names to indices and back for this to work - the
> process doing the *decoding* isn't necessarily the same process doing the
> encoding (that's kind of the point :) ). So AIUI, the name still needs to
> be present. The documentation
> <https://godoc.org/encoding/gob#hdr-Encoding_Details> says so too:
>
> Interface values are transmitted as a string identifying the concrete type
>> being sent (a name that must be pre-defined by calling Register), followed
>> by a byte count of the length of the following data (so the value can be
>> skipped if it cannot be stored), followed by the usual encoding of concrete
>> (dynamic) value stored in the interface value. (A nil interface value is
>> identified by the empty string and transmits no value.) Upon receipt, the
>> decoder verifies that the unpacked concrete item satisfies the interface of
>> the receiving variable.
>
>
> I wish I could help more :) I'd be interested to see how you get this
> resolved though (and maybe someone who used gob more can chime in). AIUI it
> *should* be possible to do what you want, so once we figured out how, it
> would probably be super helpful to contribute it as a runnable example.
>
>   But then, when I change your code to let gob do the encoding itself, the
>> name is suddenly there: https://play.golang.org/p/Qz7zDKL047z, so
>> probably the absence of the type name is part of the problem.
>>
>
>>
>>> And I agree that this probably shouldn't panic, but instead return an
>>> error. But given that the encoded bytes don't contain the name of the
>>> concrete struct, there is no way the decoder can know where you want to put
>>> it, without giving it the correct type.
>>>
>>
>> Yes, an informative error instead of the hard to interpret panic would be
>> nice.  I wonder whether this is indeed intended behaviour, or whether this
>> is some kind of bug in the encoding/gob package.
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/golang-nuts/32c27653-c50b-42cd-a525-8c9e9298bf60%40googlegroups.com
>> <https://groups.google.com/d/msgid/golang-nuts/32c27653-c50b-42cd-a525-8c9e9298bf60%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfHDb0dXOJas6otGdv1t8J17fhdHstTdVQZX1iUVc-Hk5g%40mail.gmail.com.

Reply via email to