这个:
type Form Rectangle
创建一个名为Form 的新 类型,将Rectangle 作为其基础 类型。
这意味着Rectangle(它是一个结构)的字段也将为Form定义。
但方法绑定到特定类型。当您创建一个新类型 (Form) 时,该新类型将没有其底层类型的任何方法,因此您不能调用 c.SomethingElse(),因为 SomethingElse() 是 Rectangle 类型的方法。
c.Circle.Something() 有效,因为c.Circle 是Circle 类型的字段,而Something() 是Circle 类型的方法。
如果要调用Rectangle.SomethingElse() 方法,则需要Rectangle 类型的值(接收器类型为Rectangle)。由于Form 的底层类型是Rectangle,因此您可以使用简单类型conversion 从Form 类型的值中简单地获取Rectangle 类型的值:
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,因为前者是后者的底层类型,通过转换,我们有一个SortRectangle 类型的值,可以传递到sort.Sort(),以便对其进行排序:
rs := []Rectangle{}
// Sort rs:
sort.Sort(SortRectangle(rs))
请注意,像上面SortRectangle(rs)这样的转换只改变了运行时类型信息,它不会改变rs的内存表示,所以它非常安全和高效 em>。
如果您希望新类型具有“旧”类型的方法,请使用嵌入。请参阅 Ainar-G 的答案。实际上,您已经通过在Rectangle 中嵌入Circle 来做到这一点:Rectangle 类型有一个方法Something(),因为Something() 是Circle 的一个方法:
Rectangle{}.Something() // Prints "something"