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