You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
What version of Go are you using (go version)?
1.19
What operating system and processor architecture are you using?
Initially found on Windows 10, x64, but also reproducible on go.dev/play
What did you do?
Create a struct with single int-typed private field and a custom GobEncode() method for it.
Use said struct in another struct as a public field, and try to encode the external struct with gob.
Overly simplified version: https://go.dev/play/p/iRRTIzvixOk
What did you expect to see?
GobEncode() gets called on Structy when the wrapping struct is encoded.
What did you see instead?
GobEncode() did not get called.
inp1: if the struct isn't a field in another struct the function gets called
inp2: (original case)
inp3: if the value in the struct is not 0, the encode function gets called
inp4: the function does not get called regardless of other fields having (non-zero) value in the wrapping struct
inp5: the function gets called if the wrapping struct has a pointer for the wrapped struct
inp6: the internal struct has multiple fields, all zero valued, the custom GobEncode is not called
inp7: the other internal field has a non-zero value, GobEncode is called
My guess is that this behavior is related to the struct being the zero value of its type. I'm not entirely convinced if this is a bug or just an "expected" side-effect of zero values, in the later case it would be good to call this out in the documentation for GobEncode(), as this doesn't really feel like complete control. It is definitely confusing at first glance that it only happens in some of the cases.
Some context on the actual use case this is coming from:
The struct with the private field is an enum-like type, the goal is to prevent invalid values showing up ~ever (so 0 has to be one of the valid ones, as someone can create the struct itself, but not directly set the value - it isn't perfect, but much better than just creating a type that is just int, where one can use any constant as a value).
The encoding actually maps the values to the strings versions of the enum values in GobEncode(), so the enum to int mapping can change without needing to keep the two sides talking in sync / compiled from the same version (the code for this part is generated)
As a workaround I can add a second field containing a dummy non-zero value to the enum struct, (luckily when the enum struct is inside another one there is some other processing done on it before being output, so even if a completely zero struct is created the dummy field can still be filled in before being handed to gob).
The text was updated successfully, but these errors were encountered:
mengzhuo
changed the title
GobEncode not called for wrapped struct with only zero values inside
encoding/gob: Encode not called for wrapped struct with only zero values inside
Nov 21, 2022
1.19
Initially found on Windows 10, x64, but also reproducible on go.dev/play
Create a struct with single int-typed private field and a custom GobEncode() method for it.
Use said struct in another struct as a public field, and try to encode the external struct with gob.
Overly simplified version: https://go.dev/play/p/iRRTIzvixOk
GobEncode() gets called on Structy when the wrapping struct is encoded.
GobEncode() did not get called.
Doing more experimentation (see https://go.dev/play/p/gugr1jzmAtz):
My guess is that this behavior is related to the struct being the zero value of its type. I'm not entirely convinced if this is a bug or just an "expected" side-effect of zero values, in the later case it would be good to call this out in the documentation for GobEncode(), as this doesn't really feel like complete control. It is definitely confusing at first glance that it only happens in some of the cases.
Some context on the actual use case this is coming from:
As a workaround I can add a second field containing a dummy non-zero value to the enum struct, (luckily when the enum struct is inside another one there is some other processing done on it before being output, so even if a completely zero struct is created the dummy field can still be filled in before being handed to gob).
The text was updated successfully, but these errors were encountered: