I want to check that two structs are equal, but have some problem:
package main
import (
"fmt"
"reflect"
)
type T struct {
X int
Y string
Z []int
M map[string]int
}
func main() {
t1 := T{
X:1,
Y:"lei",
Z:[]int{1,2,3},
M:map[string]int{
"a":1,
"b":2,
},
}
t2 := T{
X:1,
Y:"lei",
Z:[]int{1,2,3},
M:map[string]int{
"a":1,
"b":2,
},
}
fmt.Println(t2 == t1)
//error - invalid operation: t2 == t1 (struct containing []int cannot be compared)
fmt.Println(reflect.ValueOf(t2) == reflect.ValueOf(t1))
//false
fmt.Println(reflect.TypeOf(t2) == reflect.TypeOf(t1))
//true
//Update: slice or map
a1 := []int{1,2,3,4}
a2 := []int{1,2,3,4}
fmt.Println(a1==a2)
//invalid operation: a1 == a2 (slice can only be compared to nil)
m1 := map[string]int{
"a":1,
"b":2,
}
m2 := map[string]int{
"a":1,
"b":2,
}
fmt.Println(m1==m2)
// m1 == m2 (map can only be compared to nil)
}
reflect.DeepEqual
is often incorrectly used to compare two like structs, as in your question.cmp.Equal
is a better tool for comparing structs.To see why reflection is ill-advised, let's look at the documentation:
If we compare two
time.Time
values of the same UTC time,t1 == t2
will be false if they're metadata timezone is different.go-cmp
looks for theEqual()
method and uses that to correctly compare times.Example:
The reflect.DeepEqual can help you. You should note the situation with
nil
. You can implement anObjectEqual
function like this:Here's how you'd roll your own function http://play.golang.org/p/Qgw7XuLNhb
You can use reflect.DeepEqual, or you can implement your own function (which performance wise would be better than using reflection):
http://play.golang.org/p/CPdfsYGNy_