Closed
Description
With jsonv2
, when encoding a struct with a field of type of any
and an omitempty
tag, a empty string value will cause the field to be omitted. Whereas encoding/json
only omits these fields when the value is nil
.
This behaviour doesn't exactly match the docs:
https://pkg.go.dev/encoding/json#Marshal
The "omitempty" option specifies that the field should be omitted from the encoding if the field has an empty value, defined as false, 0, a nil pointer, a nil interface value, and any empty array, slice, map, or string.
Test to demonstrate difference in behaviour:
package jsonv2test
import (
"bytes"
"encoding/json"
"testing"
jsonv2 "github.com/go-json-experiment/json"
)
func TestOmitEmpty(t *testing.T) {
type Foo struct {
Bar any `json:",omitempty"`
}
foo := Foo{Bar: ""}
bs, err := json.Marshal(foo)
if err != nil {
t.Fatal(err)
}
bs2, err := jsonv2.Marshal(foo)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(bs, bs2) {
t.Fatalf("not equal:\n%s\n%s", bs, bs2)
}
}
Output:
=== RUN TestOmitEmpty
jsonv2_test.go:30: not equal:
{"Bar":""}
{}
--- FAIL: TestOmitEmpty (0.00s)
Activity
dsnet commentedon Sep 25, 2024
Hi, thanks for the report. You are correct that it does not perform identically.
The meaning of
omitempty
is altered in v2 to be:The problem with
omitempty
in v1 is that the definition was too narrow (e.g., it couldn't omit struct types). Theomitzero
option is being added to expand this and will be backported into v1 "encoding/json". See golang/go#45669. Most usages ofomitempty
should probably be usingomitzero
in the future.You can read golang/go#63397 (comment) for more information.
dsnet commentedon Sep 25, 2024
Closing as inactionable.
Feel free to continue discussion at golang/go#63397 (comment).