数组里保存的是实体类型实现的函数,所以当函数传入不同的实体类型时,调用的实际上是不同的函数实现,从而实现多态。
运行一下代码:
I am a student.
{19}
I am a programmer.
{100}
10. Go 接口与 C++ 接口有何异同
接口定义了一种规范,描述了类的行为和功能,而不做具体实现。
C++ 的接口是使用抽象类来实现的,如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。纯虚函数是通过在声明中使用 "= 0" 来指定的。例如:
class Shape
{
public:
// 纯虚函数
virtual double getArea() = 0;
private:
string name; // 名称
};
设计抽象类的目的,是为了给其他类提供一个可以继承的适当的基类。抽象类不能被用于实例化对象,它只能作为接口使用。
派生类需要明确地声明它继承自基类,并且需要实现基类中所有的纯虚函数。
C++ 定义接口的方式称为“侵入式”,而 Go 采用的是 “非侵入式”,不需要显式声明,只需要实现接口定义的函数,编译器自动会识别。
C++ 和 Go 在定义接口方式上的不同,也导致了底层实现上的不同。C++ 通过虚函数表来实现基类调用派生类的函数;而 Go 通过 itab
中的 fun
字段来实现接口变量调用实体类型的函数。C++ 中的虚函数表是在编译期生成的;而 Go 的 itab
中的 fun
字段是在运行期间动态生成的。原因在于,Go 中实体类型可能会无意中实现 N 多接口,很多接口并不是本来需要的,所以不能为类型实现的所有接口都生成一个 itab
, 这也是“非侵入式”带来的影响;这在 C++ 中是不存在的,因为派生需要显示声明它继承自哪个基类。
参考资料
【包含反射、接口等源码分析】https://zhuanlan.zhihu.com/p/27055513
【虚函数表和C++的区别】https://mp.weixin.qq.com/s/jU9HeR1tOyh-ME5iEYM5-Q
【具体类型向接口赋值】https://tiancaiamao.gitbooks.io/go-internals/content/zh/07.2.html
【Go夜读群的讨论】https://github.com/developer-learning/reading-go/blob/master/content/discuss/2018-08-30-understanding-go-interfaces.md
【廖雪峰 鸭子类型】https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431865288798deef438d865e4c2985acff7e9fad15e3000
【值类型和指针类型,iface源码】https://www.jianshu.com/p/5f8ecbe4f6af
【总体说明itab的生成方式、作用】http://www.codeceo.com/article/go-interface.html
【conv系列函数的作用】https://blog.csdn.net/zhonglinzhang/article/details/85772336
【convI2I itab作用】https://www.jianshu.com/p/a5e99b1d50b1
【interface 源码解读 很不错 包含反射】http://wudaijun.com/2018/01/go-interface-implement/
【what why how思路来写interface】http://legendtkl.com/2017/06/12/understanding-golang-interface/
【有汇编分析,不错】http://legendtkl.com/2017/07/01/golang-interface-implement/
【第一幅图可以参考 gdb调试】https://www.do1618.com/archives/797/golang-interface%E5%88%86%E6%9E%90/
【类型转换和断言】https://my.oschina.net/goal/blog/194308
【interface 和 nil】https://my.oschina.net/goal/blog/194233
【函数和方法】https://www.jianshu.com/p/5376e15966b3
【反射】https://flycode.co/archives/267357
【接口特点列表】https://segmentfault.com/a/1190000011451232
【interface 全面介绍,包含C++对比】https://www.jianshu.com/p/b38b1719636e
【Go四十二章经 interface】https://github.com/ffhelicopter/Go42/blob/master/content/42_19_interface.md
【对Go接口的反驳,有说到接口的定义】http://blog.zhaojie.me/2013/04/why-i-dont-like-go-style-interface-or-structural-typing.html
【gopher 接口】http://fuxiaohei.me/2017/4/22/gopherchina-2017.html
【译文 还不错】https://mp.weixin.qq.com/s/tBg8D1qXHqBr3r7oRt6iGA
【infoQ 文章】https://www.infoq.cn/article/go-interface-talk
【Go接口详解】https://zhuanlan.zhihu.com/p/27055513
【Go interface】https://sanyuesha.com/2017/07/22/how-to-understand-go-interface/
【getitab源码说明】https://www.twblogs.net/a/5c245d59bd9eee16b3db561d
【浅显易懂】https://yami.io/golang-interface/
【golang io包的妙用】https://www.jianshu.com/p/8c33f7c84509
【探索C++与Go的接口底层实现】https://www.jianshu.com/p/073c09a05da7
https://github.com/teh-cmc/go-internals/blob/master/chapter2_interfaces/README.md
【汇编层面】http://xargin.com/go-and-interface/
【有图】https://i6448038.github.io/2018/10/01/Golang-interface/
【图】https://mp.weixin.qq.com/s/px9BRQrTCLX6