我想检查两个结构是否相等,但有一些问题:
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)
}
答案 0 :(得分:116)
您可以使用reflect.DeepEqual,或者您可以实现自己的功能(性能明智优于使用反射):
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))
答案 1 :(得分:36)
reflect.DeepEqual
经常被错误地用来比较两个类似的结构,就像你的问题一样。
cmp.Equal
是比较结构的更好工具。
要了解为何反思不明智,请查看documentation:
如果导出和未导出的相应字段非常相等,则结构值非常相等。
...
数字,bools,字符串和通道 - 如果使用Go' = =运算符相等则非常相等。
如果我们比较相同UTC时间的两个time.Time
值,如果他们的元数据时区不同,则t1 == t2
将为false。
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
答案 2 :(得分:15)
以下是您如何推广自己的功能http://play.golang.org/p/Qgw7XuLNhb
func compare(a, b T) bool {
if &a == &b {
return true
}
if a.X != b.X || a.Y != b.Y {
return false
}
if len(a.Z) != len(b.Z) || len(a.M) != len(b.M) {
return false
}
for i, v := range a.Z {
if b.Z[i] != v {
return false
}
}
for k, v := range a.M {
if b.M[k] != v {
return false
}
}
return true
}
答案 3 :(得分:7)
自July 2017起,您可以将cmp.Equal
与cmpopts.IgnoreFields
选项一起使用。
func TestPerson(t *testing.T) {
type person struct {
ID int
Name string
}
p1 := person{ID: 1, Name: "john doe"}
p2 := person{ID: 2, Name: "john doe"}
println(cmp.Equal(p1, p2))
println(cmp.Equal(p1, p2, cmpopts.IgnoreFields(person{}, "ID")))
// Prints:
// false
// true
}
答案 4 :(得分:1)
如果要在单元测试中进行比较,可以方便地选择EqualValues中的testify函数。
答案 5 :(得分:1)
如果你想比较简单的一级结构,最好和最简单的方法是 if
语句。
像这样if s1 == s2
这是一个简单的例子:
type User struct {
name string
email string
}
func main() {
u1 := User{
name: "Iron Man",
email: "ironman@avengers.com",
}
u2 := User{
name: "Iron Man",
email: "ironman@avengers.com",
}
// Comparing 2 structs
if u1 == u2 {
fmt.Println("u1 is equal to u2")
} else {
fmt.Println("u1 is not equal to u2")
}
}
结果:u1 is equal to u2
你可以玩这个here。