Обратите внимание, что простую структуру, подобную указанной в вопросе, можно сравнить с ==
.
func main() {
a := &A{Foo: "qwer", Bar: 1}
b := &A{Foo: "zxcv", Bar: 1}
c := &A{Foo: "qwer", Bar: 1}
d := &A{Foo: "zxcv", Bar: 1}
fmt.Println(*a == *b)
fmt.Println(*a == *c)
fmt.Println(*b == *d)
}
https://play.golang.org/p/7W8qk6db4Uu
Примечание также, что порядок полей - stati c, для сравнения значений двух структур одного типа вы можете сделать basi c l oop и использовать i
для доступа к соответствующим полям (типам и значениям) оба экземпляра структуры.
т.е. функция getFieldValueByname
не нужна, она вам не нужна.
func testRefactor(a, b *A) {
av := reflect.ValueOf(a).Elem()
bv := reflect.ValueOf(b).Elem()
at := av.Type()
bt := bv.Type()
for i := 0; i < av.NumField(); i++ {
afv := av.Field(i)
bfv := bv.Field(i)
aft := at.Field(i)
bft := bt.Field(i)
fmt.Printf("a.%s <%s> = %v\n", aft.Name, aft.Type, afv)
fmt.Printf("b.%s <%s> = %v\n", bft.Name, bft.Type, bfv)
fmt.Printf("== ? %t\n", afv.Interface() == bfv.Interface())
fmt.Println()
}
}
https://play.golang.org/p/G1EhMeYYqud
Для объединения значений двух разных структур вы можете начать с этого:
func testRefactor(a, b interface{}) {
av := reflect.ValueOf(a).Elem()
bv := reflect.ValueOf(b).Elem()
at := av.Type()
bt := bv.Type()
for i := 0; i < av.NumField(); i++ {
afv := av.Field(i)
aft := at.Field(i)
bfv := bv.FieldByName(aft.Name)
bft, ok := bt.FieldByName(aft.Name)
if !ok || aft.Type != bft.Type {
continue
}
fmt.Printf("a.%s <%s> = %v\n", aft.Name, aft.Type, afv)
fmt.Printf("b.%s <%s> = %v\n", bft.Name, bft.Type, bfv)
fmt.Printf("== ? %t\n", afv.Interface() == bfv.Interface())
fmt.Println()
if afv.Interface() != bfv.Interface() {
afv.Set(bfv)
}
}
}
https://play.golang.org/p/9alFY4oBNZh