두 개의 구조체, 슬라이스 및 맵이 동일한 지 확인하고 싶습니다.
하지만 다음 코드에 문제가 있습니다. 관련 라인에서 내 의견을 참조하십시오.
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 을 사용 하거나 자체 함수를 구현할 수 있습니다 (반사를 사용하는 것보다 성능이 더 낫습니다).
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))
답변
reflect.DeepEqual
질문에서와 같이 두 개의 유사한 구조체를 비교하는 데 종종 잘못 사용됩니다.
cmp.Equal
구조체를 비교하는 데 더 좋은 도구입니다.
반사가 잘못된 이유를 확인하려면 문서를 살펴 보겠습니다 .
내 보낸 필드와 내 보내지 않은 해당 필드가 모두 동일한 경우 구조 값은 완전히 동일합니다.
….
숫자, 부울, 문자열 및 채널-Go의 == 연산자를 사용하여 동일하면 완전히 동일합니다.
time.Time
동일한 UTC 시간의 두 값을 비교 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
답변
다음은 자신의 함수를 롤링하는 방법입니다. 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
}
답변
2017 년 7 월 부터 옵션 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
}