Я хочу проверить, равны ли две структуры, срезы и карты.
Но у меня проблемы со следующим кодом. Смотрите мои комментарии в соответствующих строках.
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)
}
go
go-reflect
leiyonglin
источник
источник
Ответы:
Вы можете использовать reflection.DeepEqual или реализовать свою собственную функцию (что с точки зрения производительности было бы лучше, чем использование отражения):
http://play.golang.org/p/CPdfsYGNy_
источник
reflect.DeepEqual
часто неправильно используется для сравнения двух подобных структур, как в вашем вопросе.cmp.Equal
- лучший инструмент для сравнения структур.Чтобы понять, почему рефлексия не рекомендуется, давайте посмотрим на документацию :
Если мы сравним два
time.Time
значения одного и того же времени UTC,t1 == t2
будет false, если часовой пояс их метаданных отличается.go-cmp
ищетEqual()
метод и использует его для правильного сравнения времени.Пример:
источник
go-cmp
а не использоватьreflect
.Вот как можно свернуть собственную функцию http://play.golang.org/p/Qgw7XuLNhb
источник
if len(a.Z) != len(b.Z) || len(a.M) != len(b.M) { return false }
, потому что в одном из них могут быть дополнительные поля.С июля 2017 года можно использовать
cmp.Equal
сcmpopts.IgnoreFields
опцией.источник
Если вы сравниваете их в тестовом модуле , удобная альтернатива EqualValues функционировать в даче показаний .
источник