Go 如何获取父嵌入结构字段值?
我的包中有以下结构Go 如何获取父嵌入结构字段值?,go,Go,我的包中有以下结构 type Animal struct { Id string // and some more common fields } 使用我的软件包的用户应该能够实现自己的动物。由于我的一个方法需要Id,用户必须嵌入我的结构 type Dog struct { Animal Name string Legs int } 在我的软件包中,我有一个保存功能,可以将动物保存到数据库中。因为我不知道用户的类型,所以必须使用接口{}作为参数类型。我的问题是:如何从父结
type Animal struct {
Id string
// and some more common fields
}
使用我的软件包的用户应该能够实现自己的动物。由于我的一个方法需要Id,用户必须嵌入我的结构
type Dog struct {
Animal
Name string
Legs int
}
在我的软件包中,我有一个保存功能,可以将动物保存到数据库中。因为我不知道用户的类型,所以必须使用接口{}作为参数类型。我的问题是:如何从父结构动物获取Id?目前,我使用了一些JSON解析和解组,但这是go/go的方法吗
func put(doc interface{}) error {
res, err := json.Marshal(doc)
if err != nil {
return err
}
var animal *Animal
err = json.Unmarshal(res, &animal)
if err != nil {
return err
}
fmt.Println(animal.Id) // finally I have the Id
// ...
}
用法
也许您可以添加一个接口,以确保获得对父结构的引用:
type AnimalGetter interface {
GetAnimal() *Animal
}
func (dog *Dog) GetAnimal() *Animal {
return &dog.Animal
}
这将允许save方法执行类型断言AnimalGetter:
func save(obj interface{}) {
animal := obj.(AnimalGetter)
fmt.Printf("%v\n", animal.GetAnimal())
}
请参阅中的完整示例
输出:
&{{dogid} wouf 0}
&{dogid}
更简单:
func save(animal AnimalGetter) {
fmt.Printf("%v\n", animal.GetAnimal())
}
您可以使用这个小的反射技巧来实现,尽管使用@VonC建议的接口可能是一种更实用、更惯用的方法 不管怎么说,反射也可以实现同样的效果:
func main() {
d := Dog {
Animal { "id1111" },
"Barky",
4,
}
fmt.Println(reflect.ValueOf(d).FieldByName("Animal").Interface().(Animal))
}
这里的方法是将Animal声明为接口:
type Animal interface {
ID() int
Name() string
// Other Animal field getters here.
}
然后,save可以将Animal作为参数,并使用Animal的方法获取它需要的所有信息
另一种可能的方法是使用包从结构中获取动物场,但这将比使用接口更麻烦、更脏,而且可能更慢。为什么不让saveAnimalGetter保存施法?@不是高尔夫球手确定,我只是使用了问题中提到的签名或saveinterface{}。我已经按照你的建议编辑了答案。小挑剔:getter应该被称为Animal,而不是GetAnimal。@VonC你的方法甚至可以通过使动物本身成为animalGetter来简化,然后不需要为每个动物重新实现此功能。以下是我对您建议的看法:@Ainar-G我尝试过给它命名为动物,但失败了,使用了一个Dog-field动物和一个Dog-method动物:重复的名称使编译变得不可能。一开始我避免了思考,更喜欢让API需要让动物更可见。但反思当然可以奏效。
type Animal interface {
ID() int
Name() string
// Other Animal field getters here.
}