2017-09-13 87 views
0

我想從Go結構中獲得嵌入式類型。下面是一個演示這個例子的程序。有沒有辦法編寫myfunc()而沒有列舉可以輸入的每種類型? https://play.golang.org/p/5wp14O660m如何從GO結構中獲取嵌入式類型?

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結構在外部項目存在。我無法控制他們。

+0

不是,它的太短精靈作爲答案。記住:'interface {}'什麼也沒說。這就是爲什麼你必須做所有的工作, – Volker

+0

好的。那麼請回答這個問題? – codefx

+2

難道你不能只是讓所有的類型實現一個方法來返回'ObjectMeta'? – JimB

回答

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

+0

感謝您的代碼片段。 – codefx

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

+0

這些類型存在於外部項目中。我無法控制他們 – codefx