package main import ( "fmt" "reflect" ) type Log struct { Path string Level string } func (l *Log) Conversion(i interface{}) { if data, ok := i.(*Log); ok { if data != nil { if len(data.Path) > 0 { l.Path = data.Path } if len(data.Level) > 0 { l.Level = data.Level } } } } type Storage struct { Type string ServerList []string } func (s *Storage) Conversion(i interface{}) { if data, ok := i.(*Storage); ok { if data != nil { if len(data.Type) > 0 { s.Type = data.Type } } } } type Server struct { LogConfig *Log StorageConfig *Storage } func main() { def := Server{ LogConfig: &Log{ Path: "/your/old/log/path/", Level: "info", }, StorageConfig: &Storage{ Type: "zookeeper", ServerList: []string{"127.0.0.1:2181"}, }, } fmt.Println(def) cur := Server{ LogConfig: &Log{ Path: "/your/new/log/path/", Level: "debug", }, StorageConfig: &Storage{ Type: "etcd", ServerList: []string{"127.0.0.1:2379"}, }, } fmt.Println(cur) defV := reflect.ValueOf(def) curV := reflect.ValueOf(cur) for k := 0; k < defV.NumField(); k++ { in := make([]reflect.Value, 1) in[0] = reflect.ValueOf(curV.Field(k).Interface()) defV.Field(k).MethodByName("Conversion").Call(in) } fmt.Println(def.LogConfig) fmt.Println(def.StorageConfig) }