题外
我认为我们还是有必要先区分函数(function)和方法(method)。两者最明显的区别就是方法是和对象绑定的。下面是Stackoverflow上面的高票回答:
A function is a piece of code that is called by name. It can be passed data to operate on (i.e. the parameters) and can optionally return data (the return value). All data that is passed to a function is explicitly passed.
A method is a piece of code that is called by a name that is associated with an object. In most respects it is identical to a function except for two key differences:
- A method is implicitly passed the object on which it was called.
- A method is able to operate on data that is contained within the class (remembering that an object is an instance of a class - the class is the definition, the object is an instance of that data).
函数的传参和返回值都是显式的,而方法则可以在内部访问、操作对象的成员变量,另外还有作用域等差异,因编程语言不同而各异。
第六章 方法
< P156 >
- 方法名不能与字段相同;
- 可以给同一个包内的任何具名类型声明方法,只要它的底层类型不是指针或
interface
;
< P158 >
- 如果一个方法的接收器是指针,我们可以直接用变量调用(不用手动解引用),编译器会进行隐式转换;所以如果用不能获取到地址的接收器调用编译器会报错(不通过变量直接使用一个值,一般都无法进行寻址);
- 如果类型
T
的方法有指针接收器类型,要避免拷贝T
的实例,因为会违反内部不变原则;例如共享底层空间时,会发生无法预料的结果; nil
也是合法的接收器值;
< P163 >
- 编译器自顶向下查找方法,先是类型自身定义的,再到内嵌类型提升(promoted)上来的,然后是内嵌类型的再下一级……如果同一级中有同名方法,编译器会报错;
< P164 >
- 可以用
t.f
或(*t).f
生成方法值(method value),会绑定当前接收器,之后可以像普通函数一样调用; - 可以用
T.f
或(*T).f
生成方法表达式(method expression),在第一个参数指定接收器;
上面两条在魔改公用库时非常好用,能保证API向后兼容 :D