今天研究一下interface
https://mp.weixin.qq.com/s/EbxkBokYBajkCR-MazL0ZA
1.go语言是一门静态语言,但是通过接口实现了鸭子类型
2.值接收者和指针接受者的区别
调用方法的时候,值类型既可以调用值接收者的方法,也可以调用指针接收者的方法;指针类型既可以调用指针接收者的方法,也可以调用值接收者的方法。-----只有方法,不含接口时
如果实现了接收者是值类型的方法,会隐含地也实现了接收者是指针类型的方法
![](https://img.haomeiwen.com/i12841621/9ae03bda40ec1eef.png)
两者使用区分:
方法能够修改接收者指向的值。避免在每次调用方法时复制该值,在值的类型为大型结构体时,这样做会更加高效。如果类型的成员都是由 Go 语言里内置的原始类型,如字符串,整型值等,那就定义值接收者类型的方法。像内置的引用类型,如 slice,map,interface,channel,这些类型比较特殊,声明他们的时候,实际上是创建了一个 header, 对于他们也是直接定义值接收者类型的方法。这样,调用函数时,是直接 copy 了这些类型的 header,而 header 本身就是为复制设计的。
3.iface 和 eface 的区别是什么
iface的结构type iface struct { tab *itab data unsafe.Pointer}
type iface struct { tab *itab data unsafe.Pointer},itab结构体中inter interfacetype中的mhdr表示接口所定义的函数列表, data是数据指针,则指向具体的数据。它们分别被称为动态类型和动态值
![](https://img.haomeiwen.com/i12841621/52a22753e887005f.png)
而eface只维护了一个type字段type eface struct { _type *_type data unsafe.Pointer}
可以看到eface的_type和iface中interfacetype中的_type,go中的语言类型都是基于这个结构体的,这就是反射的基础
![](https://img.haomeiwen.com/i12841621/389077dd27edc078.png)
4.类型转换和断言
类型转换:<结果类型> := <目标类型> (<表达式>)
断言:<目标类型的值>,<布尔参数> := <表达式>.( 目标类型 )
5.接口转换的原理 ------有些难懂,需看原文
当判定一种类型是否满足某个接口时,Go 使用类型的方法集和接口所需要的方法集进行匹配,如果类型的方法集完全包含接口的方法集,则可认为该类型实现了该接口
(1.具体类型转空接口时,_type 字段直接复制源类型的 _type;调用 mallocgc 获得一块新内存,把值复制进去,data 再指向这块新内存。
(2.具体类型转非空接口时,入参 tab 是编译器在编译阶段预先生成好的,新接口 tab 字段直接指向入参 tab 指向的 itab;调用 mallocgc 获得一块新内存,把值复制进去,data 再指向这块新内存。
(3.而对于接口转接口,itab 调用 getitab 函数获取。只用生成一次,之后直接从 hash 表中获取。
6.interface实现多态
(1. 一种类型具有多种类型的能力
(2.允许不同的对象对同一消息做出灵活的反应
(3.以一种通用的方式对待个使用的对象
(4.非动态语言必须通过继承和接口的方式来实现
![](https://img.haomeiwen.com/i12841621/3fca3947c0bb9d1a.png)
网友评论