liveBook · Manning

Reflect.DeepEqual

As explained in 100 Go Mistakes and How to Avoid Them

reflect.DeepEqual is a Go function that recursively determines whether two values are deeply equal.

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

How 100 Go Mistakes and How to Avoid Them covers it

How deep it goes
Explains recursive traversal, supported value kinds, nil-versus-empty behavior, and reflection overhead.
Examples
Uses customer structs with slice fields, JSON unmarshaling results, and a hand-written equality method.
What it assumes
Assumes familiarity with Go equality and distinguishes comparable values from structs containing slices.
What you can do after
Apply it via Go's reflect package to compare nested values, while checking collection semantics and performance requirements.
How it connects
Connects reflection with equality operators, structs, slices, maps, nil values, unmarshaling, and manual equality methods.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Go Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.