访问GoLang中的嵌入式方法

时间:2014-09-02 14:23:13

标签: go embedding

我试图创建一些处理许多不同对象类型的泛型函数,其中一些类型嵌入了一个方便的子类型我已经创建了调用BaseObject。

我似乎无法弄清楚如何测试' Value interface {}'包含一个BaseObject,或者如何调用其中一个方法,例如: ToString()...应该返回[TestObject]而不是[BaseObject]

package Test

import(
    "fmt"
    "reflect"
)

func main() {
    Value:=TestObject{}
    TestFunction(Value)
}

//Generic function
func TestFunction(Value interface{}){

    // Does value contain BaseObject? reflect.TypeOf(Value).Containes...Implements??
    //Convert to BaseObject? BO:=Value.(BaseObject)
    // If it does, call BO.ToString()
    //fmt.println(BO.ToString())
}

//Base Object
type BaseObject struct {
}
func (this *HCObject) ToString() string {
    return "[BaseObject]"
}

//Test Object
type TestObject struct{
    BaseObject
}
func (this *TestObject) ToString() string {
    return "[TestObject]"
}

2 个答案:

答案 0 :(得分:3)

首先,有几点:

  • 最好在play.golang.org上提供工作代码示例的链接。
  • 始终指定您的代码。
  • ToString应为String。请参阅fmt.Stringer interface。
  • 正如其他人所指出的那样,尝试在Go中编写C ++ Java将会在背后留下痛苦的记录。

话虽如此,this是一个可运行的代码示例,可以满足您的需求。

func TestFunction(v interface{}) {
    fmt.Println(reflect.ValueOf(v).FieldByName("BaseObject").MethodByName("String").Call(nil)[0].String())
}

此代码使用reflect包(只有在真正需要它时才应该这样做)。我建议你玩这个例子并深入研究reflect,看看是否值得继续你使用Go的方式。

答案 1 :(得分:2)

您没有“嵌入”interface{}。接口本身有一个方法集,包含一些值和它的类型信息。

使用Type Assertion从界面中提取值。

您的测试功能可能包含以下内容:

bo, ok := value.(BaseObject)
if ok {
  fmt.Println(bo)
}

如果要检查多种类型,请使用类型开关。在您的情况下,TestObject和BaseObject是完全不同的类型; TestObject不是BaseObject。

switch bo := value.(type) {
case TestObject:
    fmt.Println("TestObject", bo)
case BaseObject:
    fmt.Println("BaseObject", bo)
}

如果您需要区分这两种类型,嵌入类型具有嵌入类型方法的超集,请定义与您需要的方法匹配的接口。

type Base interface {
    MethodA()
}

type Sub interface {
    MethodA()
    MethodB()
}

在这种情况下,SubBase,因为满足Sub接口的任何内容也会满足Base接口。