Golang的方法

方法定义

方法总是绑定对象实例,并隐式将实例做为第一实参(Receiver)

  1. 只参为当前包内命名类型定义方法
  2. 参数(Receiver)可任意命名,方法中未使用时,可省略参数名
  3. 参数(Receiver)的类型可以是T或*T,基类型T不能是接口或指针
  4. 不支持方法重载。Receiver只是参数签名的组成部分
  5. 可用实例value或pointer调用全部方法,编译器自动转换
  6. 没有构造和析构方法,通常用简单的工厂模式返回对象实例
  7. 方法只不过是一种特殊的函数
  8. 可以像字段成员那样访问匿名字段方法,编译器会自动查找
  9. 通过匿名字段可获得类似继承的能力
  10. 依据编译器查找次序,只需要外层定义同名方法,可实现"Override"

方法集

每个类型都有与之关联的方法集

  1. 类型T方法集包含全部 Receiver T方法
  2. 类型*T方法集包含全部 Receiver *T 与 T 方法
  3. 如类型 S 包含匿名字段T,则 S方法集包含 T方法
  4. 如类型 *S 包含匿名字段 *T,则 S方法集包含 *T 与 T 方法
  5. 不管嵌入 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
}