sim*_*ird 6 methods struct embedding go
所以我在这里有这个例子: 去游乐场
package main
import (
"fmt"
)
type Circle struct{}
func (c Circle) Something() {
fmt.Println("something")
}
type Rectangle struct {
Circle
}
func (a Rectangle) SomethingElse() {
fmt.Println("SomethingElse")
}
type Form Rectangle
func main() {
c := Form{}
c.Circle.Something()
c.SomethingElse()
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么我可以Something从嵌入式调用Circle,但不能Somethingelse从Rectangle内部调用Form类型.另外我不明白当我声明一种其他类型的类型时会得到什么好处,比如这里Form.
icz*_*cza 10
这个:
type Form Rectangle
Run Code Online (Sandbox Code Playgroud)
创建一个名为的新类型Form,具有Rectangle其基础类型.
这意味着也Rectangle将定义(这是一个结构)的字段Form.
但是方法绑定到特定类型.当您创建一个新类型(Form)时,该新类型将不具有其基础类型的任何方法,因此您不能c.SomethingElse()像SomethingElse()该Rectangle类型的方法一样调用.
c.Circle.Something()作品,因为c.Circle是一个类型的字段Circle,并且Something()是一种Circle类型的方法.
如果要调用Rectangle.SomethingElse()方法,则需要类型值Rectangle(接收器类型为Rectangle).由于基础类型Form是Rectangle,您可以使用简单的类型转换Rectangle从类型的值中获取类型的值:Form
Rectangle(c).SomethingElse() // This works
Run Code Online (Sandbox Code Playgroud)
创建新类型的好处是,您可以为它创建/添加自己的方法.一个常见的例子是实现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] }
Run Code Online (Sandbox Code Playgroud)
该sort.Sort()函数能够对实现的任何值进行排序sort.Interface.该[]Rectangle不会,但我们只是创造了一个新的类型SortRectangle,其确实.如果我们有一个类型的值[]Rectangle,我们可以将它转换为SortRectangle因为前者是后者的基础类型,并且通过进行转换,我们有一个SortRectangle可以传递给的类型的值sort.Sort(),以便对它进行排序:
rs := []Rectangle{}
// Sort rs:
sort.Sort(SortRectangle(rs))
Run Code Online (Sandbox Code Playgroud)
需要注意的是像上述转换SortRectangle(rs)只改变了运行时类型信息,它不会改变的内存表现形式rs,所以它的pefectly 安全和高效.
如果您希望新类型具有"旧"类型的方法,则使用嵌入.见Ainar-G的答案.实际上,你已经通过嵌入Circle来实现了这个Rectangle:类型Rectangle有一个方法Something(),因为它Something()是一个方法Circle:
Rectangle{}.Something() // Prints "something"
Run Code Online (Sandbox Code Playgroud)
Go中的一条简单规则。如果要使用类型的方法,请执行
type A struct { B }
Run Code Online (Sandbox Code Playgroud)
如果您不想要该类型的方法,请执行
type A B
Run Code Online (Sandbox Code Playgroud)
为什么我们需要第二种形式?接口,例如。有时我们不希望值满足接口,例如here。其他时候,您只需要类型而不是它的方法。
Go使您有可能获得相同的类型,但方法集为空。
| 归档时间: |
|
| 查看次数: |
1907 次 |
| 最近记录: |