如何比较结构,切片,地图是否相等?

我想检查两个结构是否相等,但是有一些问题:

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) } 

http://play.golang.org/p/AZIzW2WunI

你可以使用reflect.DeepEqual ,或者你可以实现你自己的函数(性能明智比使用reflection更好):

http://play.golang.org/p/CPdfsYGNy_

 m1 := map[string]int{ "a":1, "b":2, } m2 := map[string]int{ "a":1, "b":2, } fmt.Println(reflect.DeepEqual(m1, m2)) 

以下是你如何推出你自己的functionhttp://play.golang.org/p/Qgw7XuLNhb

 func compare(a, b T) bool { if &a == &b { return true } if aX != bX || aY != bY { return false } if len(aZ) != len(bZ) || len(aM) != len(bM) { return false } for i, v := range aZ { if bZ[i] != v { return false } } for k, v := range aM { if bM[k] != v { return false } } return true } 

reflect.DeepEqual经常被错误地用来比较两个类似的结构,就像你的问题一样。

cmp.Equal是比较结构的一个更好的工具。

要明白为什么reflection是不明智的,让我们看看文档 :

如果它们相应的字段(导出和未导出)深度相等,那么结构值是相等的。

….

数字,布尔,string和通道 – 如果使用Go的==运算符,它们是相等的。

如果我们比较两个time.Time值相同的UTC时间, t1 == t2将是假的,如果他们是元数据时区不同。

go-cmp查找Equal()方法并使用它来正确比较时间。

例:

 m1 := map[string]int{ "a": 1, "b": 2, } m2 := map[string]int{ "a": 1, "b": 2, } fmt.Println(cmp.Equal(m1, m2)) // will result in true