02 隐式实例接收参数receiver
Go限制是给一个类型定义方法只能在当前包,如果不是在当前包不能为它定义方法。像C#可以给标准库里面的类型增加扩展方法。Go涉及的思想基于的是包是个封闭状态,定义扩展方法实际上是侵入式设计。我们设计时候尽可能希望依赖关系变得很简单,因为多数时候我们并不需要把我们依赖的东西暴露出去。
定义方法两种方式,第一种选择与接口类型相绑定pointer
,还有一种选择与值类型相绑定value
。这隶属于不同的方法集。
创建一个变量,有两种执行方式,直接用值类型调用接口方法。或者取指针,指针同样会调用任何方法。编译器会帮我们处理类型的转换,这就是很典型的语法糖。换句话说,我们不应该用方法的概念理解它,这种语法糖给我们的困惑在于为什么区分*X
和X
。是因为如果把方法翻译为函数,不要用方法来理解把它转换为函数来理解,就会知道这两种函数执行方式根本不同。方法和函数的区别在于第一个参数,编译器其实做了很特殊的处理在于把方法用特殊的语法表达出来然后执行时候也用特殊的语法来表达,其实就是编译器上的语法糖。不管是方法还是函数翻译到汇编层面其实就是text段一段代码,方法和函数都要传参数。
不管是用值类型调用还是指针调用,它就是把第一个参数翻译一下。
type X int
func (x *X) pointer() {
f