dtjbcda841554
2017-09-13 21:04
采纳率: 0%
浏览 16
已采纳

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

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.

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • dsw7547 2017-09-14 02:20
    已采纳

    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

    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • donglankui1263 2017-09-14 09:03

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

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

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题