Types 在Go中,如果T2型基于T1型,是否存在任何类型的;“继承”;从T1到T2?

Types 在Go中,如果T2型基于T1型,是否存在任何类型的;“继承”;从T1到T2?,types,go,Types,Go,如果类型T2基于类型T1,而不是共享相同的数据字段,那么T1和T2之间是否存在任何关系 package main import "fmt" type T1 struct { s string } func (v *T1) F1() string { return v.s } type T2 T1 func (v *T2) F2() string { return v.s } func main() { var t1 = T1{ "xyz" } var t2

如果
类型T2
基于
类型T1
,而不是共享相同的数据字段,那么
T1
T2
之间是否存在任何关系

package main import "fmt" type T1 struct { s string } func (v *T1) F1() string { return v.s } type T2 T1 func (v *T2) F2() string { return v.s } func main() { var t1 = T1{ "xyz" } var t2 = T2{ "pdq" } s0 := t2.F1() // error - expected ok s1 := ((*T1)(&t2)).F1() // ok - expected s2 := ((*T2)(&t1)).F2() // ok - not expected fmt.Println( s0, s1, s2 ) } 包干管 输入“fmt” 类型T1结构{s string} func(v*T1)F1()字符串{return v.s} t2t1型 func(v*T2)F2()字符串{return v.s} func main(){ var t1=t1{“xyz”} 变量t2=t2{“pdq”} s0:=t2.F1()//错误-预期正常 s1:=(*T1)(&t2)).F1()//正常-应为 s2:=(*T2)(&t1)).F2()//正常-不需要 格式打印LN(s0、s1、s2) } 我在这里缺乏理解

  • 我们希望
    T2
    能够继承
    T1
    的方法,但事实并非如此

  • 所期望的
    T2
    可以强制为
    T1
    ,因为它派生自
    T1

  • 我很惊讶
    T1
    会被强制转换成
    T2
    ,但事实确实如此

  • 似乎
    T1
    T2
    之间的关系是完全对称的-我找不到任何打破对称的东西,尽管事实上一个是从另一个衍生出来的-或者这是一种错觉

  • (注意:我不是在批评或判断——我完全尊重所做的决定——只是在验证我是否理解有什么对我来说是违反直觉的——我确信我不是唯一一个!)

    之所以有效,是因为您将其强制转换为类型
    T2
    ,因此它允许
    F2
    。因此,它有望发挥作用。然后对
    T2
    对象
    t1
    调用
    F2
    函数,该对象返回
    t1.s

    s0 := t2.F1()                   // error - expected ok
    
    关于这一点,我不能肯定地告诉你,但也只能告诉你我的合理想法:

    F1是T1类型上的方法。由于t2不是T1类型,因此不能在t2上调用F1。因此,正如您所指出的,只共享数据字段,而不共享这些类型上的方法

    另见,其中指出:

    方法是在命名类型上定义的。如果将值转换为其他类型,则新值将具有新类型的方法,而不是旧类型的方法


    我可以解释为什么
    T2
    没有
    T1
    的方法。假设您需要以两种不同的方式对
    T
    类型的数据进行排序。一种方法是默认的,因此可以在
    T
    中实现
    Len
    Less
    Swap
    方法。您可以调用
    sort.sort(data)
    并以默认方式对数据进行排序。但如何对数据进行不同的排序


    您可以为type
    sortdifferly
    编写
    T
    ,并实现
    Len
    Less
    Swap
    方法。如果
    sortdifferly
    拥有
    T
    的所有方法,您就不能这样做,因为Go没有方法覆盖。但是如果没有继承,您现在可以编写
    sort.sort((sortdifference)数据)
    以不同的方式对数据进行排序


    这是一种做事的方式。这并不容易适应。

    不确定这是否会对您有所帮助,但请看一下“接口”部分下的“匿名字段”,例如中描述的“匿名字段”——它们似乎提供了类似于子类的内容


    但是在任何情况下,通过阅读Go上的教程,我产生了一个想法,Go的作者明确希望程序员避免构建继承链,而是使用嵌入/委托。

    Go不支持面向对象的类型继承

    方法绑定到单个特定类型

    A绑定A 方法的标识符。方法是 表示绑定到基类型和 仅在的选择器中可见 那种

    您可以在类型
    T1
    T2
    之间切换

    可以输入值
    x
    T
    [当]
    x
    的类型和
    T
    具有 相同的基础类型

    比如说,

    package main
    
    import (
        "fmt"
    )
    
    type T1 struct{ i int }
    
    func (t T1) String() string { return "T1" }
    
    type T2 T1
    
    func (t T2) String() string { return "T2" }
    
    func main() {
        t1 := T1{1}
        t2 := T2{2}
        fmt.Println(t1, t2)
        c1 := T1(t2)
        c2 := T2(t1)
        fmt.Println(c1, c2)
        t1 = T1(c2)
        t2 = T2(c1)
        fmt.Println(t1, t2)
    }
    
    Output:
    T1 T2
    T1 T2
    T1 T2
    

    对于另一个选项,可以使用嵌入:

    package main
    import "fmt"
    
    type T1 struct { s string }
    func (v *T1) F1() string { return v.s }
    
    type T2 struct { T1 }
    func (v *T2) F2() string { return v.s }
    
    func main() {
       a := new(T1).F1()
       // undefined (type *T1 has no field or method F2)
       // b := new(T1).F2()
       c := new(T2).F1()
       d := new(T2).F2()
       fmt.Print(a, c, d)
    }
    

    “Go没有方法覆盖”-我想这就解释了。问题是Go确实有方法阴影。如果您使用
    type sortdifferly struct{T}
    ,它将所有方法从
    T
    转发到
    sortdifferly
    ,并且仍然允许您使用专门写在
    sortdifferly
    上的方法来隐藏这些名称。您仍然可以调用
    T
    版本,甚至可以从阴影方法中调用。我真的不知道为什么他们在
    类型上不允许这样做,所以当你说
    类型T2 T1
    时,发生的是
    T1
    的结构被复制为
    T2
    的结构,因为它们具有相同的结构,可以相互重铸,另外,
    T2
    T1
    Yes没有关系。有很多转换规则。对于这个特定规则,
    T1
    T2
    具有相同的底层类型,这意味着它们也具有相同的内存大小、布局和内容。
    package main
    import "fmt"
    
    type T1 struct { s string }
    func (v *T1) F1() string { return v.s }
    
    type T2 struct { T1 }
    func (v *T2) F2() string { return v.s }
    
    func main() {
       a := new(T1).F1()
       // undefined (type *T1 has no field or method F2)
       // b := new(T1).F2()
       c := new(T2).F1()
       d := new(T2).F2()
       fmt.Print(a, c, d)
    }