@@ -71,6 +71,11 @@ import (
71
71
// false, 0, a nil pointer, a nil interface value, and any empty array,
72
72
// slice, map, or string.
73
73
//
74
+ // The "heednull" option specifies that if the field is a slice or map
75
+ // of nil value, then the value encoded will be [] or {} respectively (instead
76
+ // of "null"). If both "heednull" and "omitempty" are present, then "heednull" is
77
+ // ignored. If the field is not a slice or map, "heednull" does nothing.
78
+ //
74
79
// As a special case, if the field tag is "-", the field is always omitted.
75
80
// Note that a field with name "-" can still be generated using the tag "-,".
76
81
//
@@ -656,7 +661,18 @@ FieldLoop:
656
661
e .WriteString (f .nameNonEsc )
657
662
}
658
663
opts .quoted = f .quoted
659
- f .encoder (e , fv , opts )
664
+
665
+ if f .heedNull {
666
+ if f .typ .Kind () == reflect .Slice && fv .IsNil () {
667
+ e .WriteString ("[]" )
668
+ } else if f .typ .Kind () == reflect .Map && fv .IsNil () {
669
+ e .WriteString ("{}" )
670
+ } else {
671
+ f .encoder (e , fv , opts )
672
+ }
673
+ } else {
674
+ f .encoder (e , fv , opts )
675
+ }
660
676
}
661
677
if next == '{' {
662
678
e .WriteString ("{}" )
@@ -1039,6 +1055,7 @@ type field struct {
1039
1055
index []int
1040
1056
typ reflect.Type
1041
1057
omitEmpty bool
1058
+ heedNull bool
1042
1059
quoted bool
1043
1060
1044
1061
encoder encoderFunc
@@ -1156,6 +1173,7 @@ func typeFields(t reflect.Type) []field {
1156
1173
index : index ,
1157
1174
typ : ft ,
1158
1175
omitEmpty : opts .Contains ("omitempty" ),
1176
+ heedNull : ! opts .Contains ("omitempty" ) && opts .Contains ("heednull" ),
1159
1177
quoted : quoted ,
1160
1178
}
1161
1179
field .nameBytes = []byte (field .name )
0 commit comments