英文:
How to get embedded type from GO struct?
问题
我正在尝试从Go结构体中获取嵌入类型。下面是一个演示这一点的示例程序。有没有一种方法可以在不枚举每种可能的输入类型的情况下编写myfunc()
函数?
package main
import (
"fmt"
)
type ObjectMeta struct {
Name string
Namespace string
}
type A struct {
ObjectMeta
X string
}
type B struct {
ObjectMeta
X string
}
func myfunc(v interface{}) ObjectMeta {
switch u := v.(type) {
case *A:
return u.ObjectMeta
case A:
return u.ObjectMeta
case *B:
return u.ObjectMeta
case B:
return u.ObjectMeta
}
panic("No matching type")
}
func main() {
fmt.Println(myfunc(&A{}))
var v interface{} = &A{}
fmt.Println(v.(*ObjectMeta))
}
ObjectMeta
、A
、B
结构体存在于外部项目中,我无法对它们进行控制。
英文:
I am trying to get embedded type from Go structs. Below is an example program that demonstrates this. Is there a way to write myfunc()
without enumerating every type that can come in as input?
https://play.golang.org/p/5wp14O660m
package main
import (
"fmt"
)
type ObjectMeta struct {
Name string
Namespace string
}
type A struct {
ObjectMeta
X string
}
type B struct {
ObjectMeta
X string
}
func myfunc(v interface{}) ObjectMeta {
switch u := v.(type) {
case *A:
return u.ObjectMeta
case A:
return u.ObjectMeta
case *B:
return u.ObjectMeta
case B:
return u.ObjectMeta
}
panic("No matching type")
}
func main() {
fmt.Println(myfunc(&A{}))
var v interface{} = &A{}
fmt.Println(v.(*ObjectMeta))
}
ObjectMeta
, A
, B
structs exist in external project. I have no control over them.
答案1
得分: 1
可以使用反射(reflection)来完成,通过迭代传入值的字段:
func myfunc(v interface{}) ObjectMeta {
// 使用Elem()解引用指针
ifv := reflect.ValueOf(v).Elem()
ift := reflect.TypeOf(v).Elem()
for i := 0; i < ift.NumField(); i++ {
f := ift.Field(i)
if f.Name == "ObjectMeta" {
fv := ifv.Field(i)
return fv.Interface().(ObjectMeta)
}
}
panic("ObjectMeta未找到")
}
Playground: https://play.golang.org/p/CzMHJWhxYr
英文:
It can be done using reflection, iterating through the fields of the incoming value:
func myfunc(v interface{}) ObjectMeta {
// Elem() to de-reference pointer
ifv := reflect.ValueOf(v).Elem()
ift := reflect.TypeOf(v).Elem()
for i := 0; i < ift.NumField(); i++ {
f := ift.Field(i)
if f.Name == "ObjectMeta" {
fv := ifv.Field(i)
return fv.Interface().(ObjectMeta)
}
}
panic("ObjectMeta not found")
}
Playground: https://play.golang.org/p/CzMHJWhxYr
答案2
得分: 0
你可以定义一个接口来获取嵌入类型:
package main
import (
"fmt"
)
type HasMeta interface {
GetMeta() ObjectMeta
}
type ObjectMeta struct {
Name string
Namespace string
}
func (o ObjectMeta) GetMeta() ObjectMeta {
return o
}
type A struct {
ObjectMeta
X string
}
type B struct {
ObjectMeta
X string
}
func myfunc(o HasMeta) ObjectMeta {
return o.GetMeta()
}
func main() {
fmt.Println(myfunc(&A{}))
fmt.Println(myfunc(A{}))
fmt.Println(myfunc(&B{}))
fmt.Println(myfunc(B{}))
}
点击此处查看代码运行示例。
英文:
You can define interface which will get you that embedded type:
package main
import (
"fmt"
)
type HasMeta interface {
GetMeta() ObjectMeta
}
type ObjectMeta struct {
Name string
Namespace string
}
func (o ObjectMeta) GetMeta() ObjectMeta {
return o
}
type A struct {
ObjectMeta
X string
}
type B struct {
ObjectMeta
X string
}
func myfunc(o HasMeta) ObjectMeta {
return o.GetMeta()
}
func main() {
fmt.Println(myfunc(&A{}))
fmt.Println(myfunc(A{}))
fmt.Println(myfunc(&B{}))
fmt.Println(myfunc(B{}))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论