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

encoding/json: custom MarshalJSON() on anonymous field blocks encoding of sibling struct fields #39915

Closed
BourgeoisBear opened this issue Jun 29, 2020 · 5 comments

Comments

@BourgeoisBear
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.14.4 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"

What did you do?

When I JSON encode a struct that embeds another struct (ICustom) as an anonymous field, and that struct (ICustom) implements MarshalJSON(), only ICustom is encoded, and other fields are omitted.

When I do the same thing, but where the embedded struct doesn't implement MarshalJSON(), all fields are included.

See: https://play.golang.org/p/VKH--_G432v

What did you expect to see?

The same output for both, given the code in the example.

What did you see instead?

Sibling fields omitted.

@mvdan
Copy link
Member

mvdan commented Jun 29, 2020

This seems like a dupe of #39175.

@BourgeoisBear
Copy link
Author

@mvdan in what way? #39715 is an unmarshaling issue. This is a marshaling one.

@mvdan
Copy link
Member

mvdan commented Jun 29, 2020

It seems like the same root issue. Your method is being promoted to the main type, so it's being used to marshal the entire parent type, not just the embedded one. This is how methods in Go work.

@BourgeoisBear
Copy link
Author

BourgeoisBear commented Jun 29, 2020

That explains it. Thanks.

@BourgeoisBear
Copy link
Author

For the next person with this problem: you can embed a 2nd struct implementing a custom MarshalJSON(), and sibling fields will encode again. I made a dummy struct just for this purpose:

type JSON_Hack int

func (V JSON_Hack) MarshalJSON() ([]byte, error) {
	return []byte("null"), nil
}

type Example struct {
   Embed1WithCustomMarshaller
   JSON_Hack `json:"-"`
   Sibling1   int
   Sibling2   string
}

@golang golang locked and limited conversation to collaborators Jun 30, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants