go-json
go-json copied to clipboard
`omitempty` tag is ignored when field's type has pointer receiver in `MarshalJSON` implementation
Description
Consider any struct type A
with a field F
tagged as omitempty
, where F
has type B
.
If B
has a custom MarshalJSON
implementation with a pointer receiver, for values of A
where F
has an empty value the empty value of F
is not omitted as it should.
This seems similar to https://github.com/goccy/go-json/issues/458, but tried its fix for this and it did not work.
Example
Consider the type stringAlias
with a custom MarshalJSON
implementation with a pointer receiver:
type stringAlias string
func (d *stringAlias) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf("\"%s\"", *d)), nil
}
Now consider type withOmit
, which has a field A
tagged as omitempty
, having type stringAlias
:
type withOmit struct {
A stringAlias `json:"a,omitempty"`
}
For values of withOmit
with empty values of A, go-json
fails to omit values of this field:
func main() {
var correct, wrong withOmit
bytesCorrect, err := stdJson.Marshal(&correct) // "stdJson" is "encoding/json"
if err != nil {
panic(err)
}
bytesWrong, err := json.Marshal(&wrong)
if err != nil {
panic(err)
}
fmt.Printf("correct: %s\n", bytesCorrect) // correct: {}
fmt.Printf("wrong: %s\n", bytesWrong) // wrong: {"a":""}
}
Full code example available at https://go.dev/play/p/4njSDtWS8k5 (couldn't make it run though, it times out when downloading dependencies).