Skip to content

Commit 2b8252e

Browse files
committed
Add an option to consider nil pointers to be equivalent to zero values
Similar to NilSlicesAreEmpty and NilStructsAreEmpty, this lets one consider nil pointers and zero values as equal.
1 parent 95fb3b1 commit 2b8252e

2 files changed

Lines changed: 33 additions & 0 deletions

File tree

deep.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ var (
4343

4444
// NilMapsAreEmpty causes a nil map to be equal to an empty map.
4545
NilMapsAreEmpty = false
46+
47+
// NilPointersAreZero causes a nil pointer to be equal to a zero value.
48+
NilPointersAreZero = false
4649
)
4750

4851
var (
@@ -190,6 +193,12 @@ func (c *cmp) equals(a, b reflect.Value, level int) {
190193
if bElem {
191194
b = b.Elem()
192195
}
196+
if aElem && NilPointersAreZero && !a.IsValid() && b.IsValid() {
197+
a = reflect.Zero(b.Type())
198+
}
199+
if bElem && NilPointersAreZero && !b.IsValid() && a.IsValid() {
200+
b = reflect.Zero(a.Type())
201+
}
193202
c.equals(a, b, level+1)
194203
return
195204
}

deep_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,3 +1581,27 @@ func TestSliceOrderStruct(t *testing.T) {
15811581
t.Fatalf("expected 0 diff, got %d: %s", len(diff), diff)
15821582
}
15831583
}
1584+
1585+
func TestNilPointersAreZero(t *testing.T) {
1586+
defaultNilPointersAreZero := deep.NilPointersAreZero
1587+
deep.NilPointersAreZero = true
1588+
defer func() { deep.NilPointersAreZero = defaultNilPointersAreZero }()
1589+
1590+
type T struct {
1591+
S *string
1592+
}
1593+
1594+
a := T{S: nil}
1595+
b := T{S: new(string)}
1596+
1597+
diff := deep.Equal(a, b)
1598+
if len(diff) != 0 {
1599+
t.Fatalf("expected 0 diff, got %d: %s", len(diff), diff)
1600+
}
1601+
1602+
*b.S = "hello"
1603+
diff = deep.Equal(a, b)
1604+
if len(diff) != 1 {
1605+
t.Fatalf("expected 1 diff, got %d: %s", len(diff), diff)
1606+
}
1607+
}

0 commit comments

Comments
 (0)