在Go中,如果类型T2基于类型T1,那么T1到T2之间是否有任何“继承”?

时间:2011-06-26 13:19:04

标签: types go

如果type T2基于type T1,除了共享相同的数据字段外,T1T2之间是否有任何关系?

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 )
}

我的理解缺乏

  1. 希望T2继承T1的方法,但事实并非如此。

  2. 期待T2被强制转换为T1,因为它来自T1

  3. 感到惊讶的是,T1可能被强制转移到T2,但事实确实如此。

  4. 似乎T1T2之间的关系是完全对称的 - 我找不到任何破坏对称性的东西,尽管事实上一个实际上来自另一个 - 或者这是一个幻觉?

  5. (注意:我批评或评判 - 我完全尊重做出的决定 - 只是验证我明白对我来说有什么反直觉 - 我敢肯定我不是只有一个!)

5 个答案:

答案 0 :(得分:8)

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

Is Go an object-oriented language?

Why is there no type inheritance?

方法绑定到单个特定类型。

  

method declaration绑定一个   方法的标识符。方法是   据说要绑定基类型   仅在选择器中可见   那种类型。

您可以在T1T2类型之间convert

  

x可以converted进行输入   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

答案 1 :(得分:1)

不确定它是否会对你有所帮助,但是看看“{3}}中描述的”匿名字段“,在”接口“部分下 - 它们似乎提供了类似子类的东西。

但无论如何,通过Go上的教程阅读,我开发了一个想法,Go的作者肯定希望程序员避免构建继承链并使用嵌入/委派代替。

答案 2 :(得分:0)

s2 := ((*T2)(&t1)).F2()         // ok - not expected

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

s0 := t2.F1()                   // error - expected ok

对于这个,我不能肯定地告诉你,但也只是给你我看似合理的想法:

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

另见Go for C++ programmers,其中说明:

  

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

答案 3 :(得分:0)

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

您为type SortDifferently T类型编写Len并实施LessSwapSortDifferently方法。如果SortDifferently拥有T的所有方法,则无法执行此操作,因为Go没有方法覆盖。但是如果没有继承,您现在可以编写sort.Sort((SortDifferently)data)以不同的方式对数据进行排序。

这是Go的做事方式。要习惯它并不容易。

答案 4 :(得分:0)

对于另一种选择,您可以使用嵌入:

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)
}

https://golang.org/ref/spec#Struct_types