Comparing values with == fails when a struct contains a slice or another noncomparable field. reflect.DeepEqual recursively traverses values and reports whether they are deeply equal, including structs, slices, maps, pointers, interfaces, arrays, and basic types. section 3.13
Compare a struct containing a slice
cust1 := customer{id: "x", operations: []float64{1.}} cust2 := customer{id: "x", operations: []float64{1.}} fmt.Println(reflect.DeepEqual(cust1, cust2)) // true Using cust1 == cust2 would fail because the struct contains a slice. section 3.13
Choose the comparison deliberately:
- Use reflect.DeepEqual when runtime reflection is acceptable and values contain noncomparable fields. section 3.13
- Account for nil and empty collections: reflect.DeepEqual distinguishes them, which may matter after unmarshaling. section 3.13
- Prefer a type-specific equality method when performance matters; reflection can be about 100 times slower than == in local benchmarks. section 3.13
cust1 := customer{id: "x", operations: []float64{1.}}
cust2 := customer{id: "x", operations: []float64{1.}}
fmt.Println(reflect.DeepEqual(cust1, cust2))
Shows a runnable DeepEqual comparison for two customer values containing slices. section 3.13
func (a customer) equal(b customer) bool {
if a.id != b.id { #1
return false
}
if len(a.operations) != len(b.operations) { #2
return false
}
for i := 0; i < len(a.operations); i++ { #3
if a.operations[i] != b.operations[i] {
return false
}
}
return true
}
Shows a manual customer equality method as a performance-oriented alternative. section 3.13
