我的包中有以下结构。
type Animal struct {
Id string
// and some more common fields
}
使用我的包的用户应该能够实现自己的Animal
。由于我在我的一种方法中需要Id
,因此用户必须嵌入我的结构。
type Dog struct {
Animal
Name string
Legs int
}
在我的包中,我有save()
函数将Animal
保存到数据库。由于我不知道用户的类型,我必须使用interface{}
作为参数类型。我的问题是:如何获取Id
(来自父结构Animal
)?目前我使用了一些JSON解析和解组,但这是去/去的方式吗?
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
// ...
}
用法
func main() {
bello := Dog{
Animal: Animal{
Id: "abcd1234",
},
Name: "bello",
Legs: 4,
}
err := put(bello)
// ...
}
答案 0 :(得分:2)
也许你可以添加一个接口,以确保获得对父结构的引用:
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())
}
请参阅 play.golang.org 中的完整示例。
输出:
&{{dogid} wouf 0}
&{dogid}
简单:
func save(animal AnimalGetter) {
fmt.Printf("%v\n", animal.GetAnimal())
}
( play.golang.org )
答案 1 :(得分:2)
去/去的方法是将Animal
声明为接口:
type Animal interface {
ID() int
Name() string
// Other Animal field getters here.
}
然后,save
可以将Animal
作为参数,并使用Animal
的方法获取所需的所有信息。
另一种可能的方法是使用reflect
包来从结构中获取Animal
字段,但这将使用界面更加笨拙,更脏并且可能更慢。
答案 2 :(得分:1)
你可以用这个小的反射技巧来做到这一点,尽管使用像@VonC建议这样的接口可能是一种更实用和惯用的方法。
无论如何,这与反射相同:
func main() {
d := Dog {
Animal { "id1111" },
"Barky",
4,
}
fmt.Println(reflect.ValueOf(d).FieldByName("Animal").Interface().(Animal))
}