如何从GO结构中获取嵌入类型?

时间:2017-09-13 21:04:20

标签: go

我正在尝试从Go结构中获取嵌入类型。下面是一个演示此示例的程序。有没有办法编写myfunc()而不枚举可以作为输入进入的每种类型? 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))
}
外部项目中存在

ObjectMetaAB结构。我无法控制它们。

2 个答案:

答案 0 :(得分:0)

可以使用反射来完成,迭代传入值的字段:

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")
}

游乐场:https://play.golang.org/p/CzMHJWhxYr

答案 1 :(得分: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{}))
}

https://play.golang.org/p/CWa4k-kvvl