func Merge(a interface{}, b interface{})( d interface{}) {
aType := reflect.TypeOf(a)
if aType.Kind() != reflect.Struct {
panic("a is not a struct")
}
bType := reflect.TypeOf(b)
if bType.Kind() != reflect.Struct {
panic("b is not a struct")
}
var fields []reflect.StructField
for i:=0 ; i< aType.NumField(); i++{
fields =append(fields, aType.Field(i))
}
for i:=0 ; i< bType.NumField(); i++{
fields =append(fields, bType.Field(i))
}
dType := reflect.StructOf(fields)
dVal := reflect.Indirect(reflect.New(dType))
aVal := reflect.ValueOf(a)
bVal := reflect.ValueOf(b)
for i := 0; i < aType.NumField(); i++ {
dVal.FieldByName(aType.Field(i).Name).Set(aVal.Field(i))
}
for i := 0; i < bType.NumField(); i++ {
dVal.FieldByName(bType.Field(i).Name).Set(bVal.Field(i))
}
d = dVal.Interface()
return
}
func main() {
a, b, c := A{"John"}, B{42}, C{"World"}
d1 := Merge(a, b)
d2 := Merge(a, c)
d3 := Merge(b, c)
fmt.Printf("%#v\n",d1)
fmt.Printf("%#v\n",d2)
fmt.Printf("%#v\n",d3)
}