我试图创建一些处理许多不同对象类型的泛型函数,其中一些类型嵌入了一个方便的子类型我已经创建了调用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]"
}
答案 0 :(得分:3)
首先,有几点:
ToString
应为String
。请参阅fmt.Stringer
interface。话虽如此,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()
}
在这种情况下,Sub
是Base
,因为满足Sub
接口的任何内容也会满足Base
接口。