Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Golang:Struct and interface(Embedded) #18

Open
wisecsj opened this issue Feb 22, 2019 · 2 comments
Open

Golang:Struct and interface(Embedded) #18

wisecsj opened this issue Feb 22, 2019 · 2 comments

Comments

@wisecsj
Copy link
Owner

wisecsj commented Feb 22, 2019

结构体与接口的内嵌,有四种情况

@wisecsj wisecsj changed the title Golang:Struct and interface(内嵌与聚合) Golang:Struct and interface(combination) Feb 22, 2019
@wisecsj wisecsj changed the title Golang:Struct and interface(combination) Golang:Struct and interface(Embedded) Feb 22, 2019
@wisecsj
Copy link
Owner Author

wisecsj commented Feb 22, 2019

1.接口嵌套接口

相当于是外层接口也定义了内层接口的方法

2.接口内嵌结构体

直接编译报错

3.结构体内嵌接口

相当于结构体具有了接口的method,初始化时接口字段需要用实现了此接口的类型赋值。

外层结构体也可以作为receiver,定义与接口内部同名的方法,从而实现覆盖。

4.结构体内嵌结构体

外层结构体自动获得内层结构体的字段和方法,同3,也可以进行覆盖

@wisecsj
Copy link
Owner Author

wisecsj commented Mar 22, 2019

对于结构体A,它有实例a(类型为A),和b(类型为A),和方法funca(接收器类型为A),funcb(接收器类型为A),则有:

无论是a还是b,都可以调用方法funca和funcb,因为GO会自动隐式地帮你转换成正确的类型
虽然都可以进行调用,但是值变量只拥有值方法集,指针变量则同时拥有值方法集和指针方法集
当需要改变结构体数据时,用指针方法,不需要时,用值方法

但是对于接口变量上的指针方法与值方法:

规则一:如果使用指针方法来实现一个接口,那么只有指向那个类型的指针才能够实现对应的接口。
规则二:如果使用值方法来实现一个接口,那么那个类型的值和指针都能够实现对应的接口。

按照上面的两条规则,那究竟怎么选择是指针接收器还是值接收器呢?

何时使用值类型

(1)如果接收器是一个 map,func 或者 chan,使用值类型(因为它们本身就是引用类型)。

(2)如果接收器是一个 slice,并且方法不执行 reslice 操作,也不重新分配内存给 slice,使用值类型。

(3)如果接收器是一个小的数组或者原生的值类型结构体类型(比如 time.Time 类型),而且没有可修改的字段和指针,又或者接收器是一个简单地基本类型像是 int 和 string,使用值类型就好了。

值类型的接收器可以减少一定数量的内存垃圾生成,值类型接收器一般会在栈上分配到内存(但也不一定),在没搞明白代码想干什么之前,别为这个原因而选择值类型接收器。

何时使用指针类型

(1)如果方法需要修改接收器里的数据,则接收器必须是指针类型。

(2)如果接收器是一个包含了 sync.Mutex 或者类似同步字段的结构体,接收器必须是指针,这样可以避免拷贝。

(3)如果接收器是一个大的结构体或者数组,那么指针类型接收器更有效率。

(4)如果接收器是一个结构体,数组或者 slice,它们中任意一个元素是指针类型而且可能被修改,建议使用指针类型接收器,这样会增加程序的可读性。

最后如果实在还是不知道该使用哪种接收器,那么记住使用指针接收器是最靠谱的。

内嵌结构体的方法提升规则:

规则一:如果S包含嵌入字段T,则S和*S的方法集都包括具有接收方T的提升方法。S的方法集还包括具有接收方T的提升方法。

规则二:如果S包含嵌入字段T,则S和S的方法集都包括具有接收器T或*T的提升方法。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant