方法定义
方法总是绑定对象实例,并隐式将实例做为第一实参(Receiver)
- 只参为当前包内命名类型定义方法
- 参数(Receiver)可任意命名,方法中未使用时,可省略参数名
- 参数(Receiver)的类型可以是T或*T,基类型T不能是接口或指针
- 不支持方法重载。Receiver只是参数签名的组成部分
- 可用实例value或pointer调用全部方法,编译器自动转换
- 没有构造和析构方法,通常用简单的工厂模式返回对象实例
- 方法只不过是一种特殊的函数
- 可以像字段成员那样访问匿名字段方法,编译器会自动查找
- 通过匿名字段可获得类似继承的能力
- 依据编译器查找次序,只需要外层定义同名方法,可实现"Override"
方法集
每个类型都有与之关联的方法集
- 类型T方法集包含全部 Receiver T方法
- 类型*T方法集包含全部 Receiver *T 与 T 方法
- 如类型 S 包含匿名字段T,则 S方法集包含 T方法
- 如类型 *S 包含匿名字段 *T,则 S方法集包含 *T 与 T 方法
- 不管嵌入 T或者*T,*S方法集都包含 *T 与 T方法
用实例Value或Pointer调用方法,不受方法集约束,编译器会自动查找并转换
表现形式
instance.method(args...) ----> method value
需要绑定实例
会复制Receiver,如果不是指针时,以免后面操作影响
<type>.func(instance, args...) ----> method expression
需要显式传参
方法“还原”成函数
type Data struct {}
func (Data) TestValue(){}
func (*Data) TestPointer() {}
func main() {
var p *Data = nil
p.TestPointer()
(*Data)(nil).TestPointer() // method value
(*Data).TestPointer(nil) // method expression
p.TestValue() // invalid memory address or nil pointer dereference
(Data)(nil).TestValue() // connot convert nil to type Data
Data.TestValue(nil) // connot use nil as type Data in function argument
}