所以我在这里有这个例子: Go Playground
Something
我不明白为什么我可以从嵌入式Circle
拨打Somethingelse
,但无法从Rectangle
内的Form
拨打Form
类型。另外,当我宣布某种类型的其他类型时,我不明白我会得到什么好处,例如DN 64.6.220.251 106.19 GB 256 ? e008bc26-5d12-48b5-a381-6a175b085496 Rack1
中的。
答案 0 :(得分:9)
此:
type Form Rectangle
创建一个名为Form
的 new 类型,其{em>底层类型为Rectangle
。
这意味着Rectangle
(这是一个结构)的字段也将被定义为Form
。
但是方法绑定到特定类型。当您创建新类型(Form
)时,该新类型将不具有其基础类型的任何方法,因此您无法调用c.SomethingElse()
,因为SomethingElse()
是一种方法Rectangle
类型。
c.Circle.Something()
有效,因为c.Circle
是Circle
类型的字段,而Something()
是Circle
类型的方法。
如果要调用Rectangle.SomethingElse()
方法,则需要类型为Rectangle
的值(接收方类型为Rectangle
)。由于Form
的基础类型为Rectangle
,因此您只需使用简单类型conversion从类型Rectangle
的值中获取类型Form
的值:< / p>
Rectangle(c).SomethingElse() // This works
创建新类型的好处是,您可以为它创建/添加自己的方法。一个常见的例子是实现sort.Interface
接口。假设你有一些东西,例如[]Rectangle
,或者您无法控制的某种类型的切片(因为它是另一个包的一部分 - 并且类型的方法只能在同一个包中定义)。如果要对此切片进行排序,可以创建一个新类型,您可以为其定义方法,sort.Interface
的方法,例如:
type SortRectangle []Rectangle
func (s SortRectangle) Len() int { return len(s) }
func (s SortRectangle) Less(i, j int) bool { return s[i] <some-logic> s[j] }
func (s SortRectangle) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
sort.Sort()
函数能够对实现sort.Interface
的任何值进行排序。 []Rectangle
没有,但我们刚刚创建了一个新类型SortRectangle
。如果我们有[]Rectangle
类型的值,我们可以将它转换为SortRectangle
,因为前者是后者的基础类型,通过转换,我们有一个类型为{{1的值可以传递给SortRectangle
,以便对其进行排序:
sort.Sort()
请注意,上述rs := []Rectangle{}
// Sort rs:
sort.Sort(SortRectangle(rs))
之类的转换只会更改运行时类型信息,但不会更改SortRectangle(rs)
的内存表示,因此它完全安全和高效
如果您希望新类型具有“旧”类型的方法,则使用嵌入。见Ainar-G的答案。事实上,您已经通过在rs
中嵌入Circle
来实现此目的:Rectangle
类型的方法Rectangle
,因为Something()
是{{1}的方法}}:
Something()
答案 1 :(得分:5)
Go中的一条简单规则。如果您需要类型的方法,请执行
type A struct { B }
如果您不想想要类型的方法,请执行
type A B
为什么我们需要第二种形式? 接口,例如。有时我们不想要一个值来满足界面,例如here。其他时候你只需要类型而不是它的方法。
Go使您可以获得相同的类型,但设置为空方法。
答案 2 :(得分:1)
执行type Form Rectangle
的全部(唯一)理由是使用不同的方法定义 new 类型。在您的示例中:没有方法。 c
是一个表格,没有方法,只有存在的理由是不采用SomethingElse()
方法。
但是Form
仍会嵌入一个圆圈,可以c.Circle
访问,而Circle
也是Something()
,所以它显然有方法:active:focus
。