-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Open
Description
What did you do?
I need to Marshal some structs like
type MyType struct {
Ptr *string `json:"ptr,omitempty"`
Opt Optional[string] `json:"opt,omitempty"`
}
The Optional
is an "optional value" implementation like other languages:
opt.Has()
to check whether it is set a value,opt.Value()
gets its value.- It has
Marshal
&Unmarshal
related functions for JSON & YAML.Marshal
check whetheropt.Has()
:- if no value, then treat it as empty
- if has value, then the "optional value" is not empty (even if the real value is empty string, the "optional value" itself is not empty)
The sample code is : #75623 (comment)
By using json(v1) and other YAML libraries, it works well:
v.Ptr = nil
andv.Opt = optional.None
outputs{}
v.Ptr = &str
andv.Opt = optional.Some("")
outputs{ptr:"",opt:""}
: the pointer and optional field are not empty
What did you see happen?
But when using json(v2):
v.Ptr = nil
andv.Opt = optional.None
outputs{}
: it works as expectedv.Ptr = &str
andv.Opt = optional.Some("")
outputs{}
: the empty string (which should be treated "non-empty" for the pointer & optional value) are aggressively removed.- json(v2) does too much for the "empty value removal", maybe it's also better to accept user's "Marshal" func's decision?
- Although I found a trick by using
jsonv2.JoinOptions(jsonv1.OmitEmptyWithLegacySemantics(true))
, overall it doesn't look good or right.
What did you expect to see?
I think json(v2) package should fix and relax the "empty value removal" behavior, and clarify the "omitempty" behavior, for example, for a pointer, only nil is empty, non-nil is not-empty. And it's better to let Marshal
func to tell whether the value is empty and/or zero.
Why it is important
For API design, a non-existing field is literally different from an empty string.
- We don't want/need to output
{"ptr": null}
for callers if a field doesn't exist (nil-pointer, oroptional.None
) - The "empty string" should be kept
{ptr:"",opt:""}
for callers because they are not NULL or default value in other languages.
Metadata
Metadata
Assignees
Labels
No labels