## DEV Community

Shannon

Posted on • Updated on

# Using reflect.DeepEqual to compare data structures in Go

## Intro

When I started using Go, I would compare two slices by writing a for loop and iterating over both to make sure they were equal. After seeing some sample code using the `reflect` package, I realized this is totally unnecessary. We can compare slices, maps, structs (anything!) simply by passing them into `reflect.DeepEqual(x,y)`, which reports whether two variables are "deeply equal."

## Slice/Array Example

Let's take this function that reverses a slice:

``````func ReverseSlice(s []string) []string {
reversedSlice := make([]string, len(s))

for i, j := len(s), 0; i > 0; i, j = i-1, j+1 {
reversedSlice[j] = s[i-1]
}

return reversedSlice
}
``````

Now, I have written a test that shows the usage or comparing two slices:

``````func TestReverseSlice(t *testing.T) {
got := ReverseSlice([]string{
"person1",
"person2",
"person3",
"person4",
})

want := []string{
"person4",
"person3",
"person2",
"person1",
}

if !reflect.DeepEqual(got, want) {
t.Errorf("got %q slice but expected %q", got, want)
}
}
``````

So, pretty straightforward! However, it's really important to note that the two arrays must be in the same order. They cannot have the same values but be in a different order. The function comments specifically state: `Array values are deeply equal when their corresponding elements are deeply equal.`

## Map Example

Maps are a little different! By default, they are not going to have a specific order. For instance, a `map[string]string` is going to be constructed with a potentially random order.

So how are they compared with `DeepEqual`? They will both need to either be nil, or not nil, have the same length, and the same corresponding key/values.

In this case, I'm going to just use `main()` to showcase a few of these points with print statements:

``````func main() {
m1, m2 := make(map[string]string), make(map[string]string)

m1["person1"] = "person1"
m1["person2"] = "person2"

m2["person2"] = "person2"
m2["person1"] = "person1"

fmt.Printf("type=%T -- addr=%p -- len=%d\n", m1, &m1, len(m1))
fmt.Printf("type=%T -- addr=%p -- len=%d\n", m2, &m2, len(m2))

if reflect.DeepEqual(m1, m2) {
fmt.Println("they are equal")
} else {
fmt.Println("they are NOT equal")
}
}
``````

Specifically, we're looking to compare the type, address, and length of the map. We'll need the type and length to be the same, but the addresses should be different (but not `nil`).

Once running, you should see output similar to this:

``````type=map[string]string -- addr=0xc0000b0018 -- len=2
they are equal
``````

I'd also encourage reading the full documentation for this function in the Go docs :)

As an alternative to reflect.DeepEquals, the `github.com/google/go-cmp/cmp` package lets you compare and sort slices pretty simply:
``````sort := func(x, y string) bool { return x > y }