我想将结构A转换为B,但没有找到解决此问题的简便方法
type Bob struct {
Name string
Age int
}
type Mark struct {
Name string
Age int
HairColor string
}
任何想法?我不想为所有属性,例如
编写assign语句Mark{
Name:bob.Name,
Age: bob.Age,
}
因为如果结构A和B具有很多类似20的属性,这种方法将非常繁琐
解决方案还应该处理深度嵌套的结构
编辑:有时两个结构的底层结构都不相同,例如A具有更多的属性,例如B,反之亦然
在Go中实现此目标的一般的底层方法是使用反射。您可以查找字段的名称并适当设置值。但是,我建议使用诸如https://github.com/jinzhu/copier之类的库进行深层复制。否则,您会发现它的指针和切片等不同类型变得非常毛茸茸。
您可以简单地做:copier.Copy(&mark, &bob)
(显然,mark和bob是Mark和Bob结构的实例)。
因为Mark
和Bob
具有相同的基础类型,所以conversion可用于在两种类型之间进行转换。这是将Bob
转换为Mark
的方法:
b := Bob{Name: "Bob", Age: 22}
m := Mark(b)
编辑:OP更改了问题。更新后的答案如下。
使用反射包将匹配字段的子集从一个结构复制到另一个结构:
// copyCommonFields copies the common fields from the struct
// pointed to srcp to the struct pointed to by destp.
func copyCommonFields(destp, srcp interface{}) {
destv := reflect.ValueOf(destp).Elem()
srcv := reflect.ValueOf(srcp).Elem()
destt := destv.Type()
for i := 0; i < destt.NumField(); i++ {
sf := destt.Field(i)
v := srcv.FieldByName(sf.Name)
if !v.IsValid() || !v.Type().AssignableTo(sf.Type) {
continue
}
destv.Field(i).Set(v)
}
}
像这样使用它:
b := Bob{Name: "Bob", Age: 22, ShoeSize: 9}
var m Mark
copyCommonFields(&m, &b)
另一种可能性是将公共字段放在单独的结构中,并将其嵌入其他结构中:
type Person struct {
Name string
Age int
}
type Bob struct {
Person
}
type Mark struct {
Person
HairColor string
}
然后您可以使用以下方法创建Mark
对象:>
Mark{
Person: bob.Person,
// other initializations
}