在Go中,一种类型被强制转换为另一种类型,可以用一种方法来确定接收器的类型吗?

cc *_*ung 5 types go

如果类型T1和类型T2基于类型T,并且类型T仅从a NewT1()或者存在NewT2(),那么函数func (*T) WhoAmI()是否有任何方式可以知道它"真的"是一个T1还是T2

package main
import "fmt"
import "reflect"

type T struct { s string }
func (v *T) WhoAmI() string {

        // pull type name with reflect  
        fmt.Println( reflect.TypeOf(v).Elem().Name() )  // always prints "T"!

        // todo: if I am actually T1
        return "T1"
        // todo: else if I am actually T2
        return "T2"
}

type T1 T
func NewT1( s string ) T1 { return T1{ s } }

type T2 T
func NewT2( s string ) T2 { return T2{ s } }

func main() {
        var t1 = T1{ "xyz" }
        var t2 = T2{ "pdq" }
        s1 := ((*T)(&t1)).WhoAmI()      // would like to return "T1"
        s2 := ((*T)(&t2)).WhoAmI()      // would like to return "T2"
        fmt.Println( s1, s2 )
}

从技术上讲:

一旦t1类型T1被强制转换为类型T所以func (*T) WhoAmI()可以被称为t1完全失去它的类型真的这个事实T1?如果没有,我们如何从接收类型的方法的角度回收知识T

一般来说:

换句话说,如果一个类型基于另一个类型,如果派生类型的变量被强制转换为基类型以运行方法,那么该方法是否可以学习调用它的接收方的实际类型?

Eva*_*haw 8

不,这是不可能的.从旧类创建新类型与创建从基于类的语言中的父类继承的新类不同.在你的情况下,T对T1或T2一无所知,如果你正在调用WhoAmI方法,你有一个T型接收器的定义.

您的设计可以通过界面更好地工作.尝试更像这样的东西:

type T interface {
    WhoAmI() string
}

type T1 struct {
    s string
}

func (t *T1) WhoAmI() string { return "T1" }

type T2 struct {
    s string
}

func (t *T2) WhoAmI() string { return "T2" }
Run Code Online (Sandbox Code Playgroud)

试试吧 Go playground

T1和T2都实现了接口T,因此它们可以用作类型T.