1. 简介
Go 方法是作用在接收者(receiver)上的一个函数,接收者是某种类型的变量。因此方法是一种特殊类型的函数;
类型 T(或 *T)上的所有方法的集合叫做类型 T(或 *T)的方法集(method set);
方法集中的方法名不允许重复,不同类型的方法集中允许重复的方法名;
类型的代码和方法的代码可以不在同一个源文件中,但必须在同一个包中(因此不能为内置类型创建方法);
1.1 定义
定义格式如下:
func (recv receiver_type) methodName(parameter_list) (return_value_list) { ... }
receiver_type:接收者类型
methodName:方法名
parameter_list :参数列表
return_value_list:返回参数列表
接收者类型不可以为接口类型,不可以为指针类型,但是可以是允许类型的指针;
如果 recv 是一个指针,Go 会自动解引用,如果不需要使用接收者类型的值,可以用 _ 替换它;
2. 方法和函数的区别
函数将变量作为参数:Function1(recv)
方法在变量上被调用:recv.Method1()
3. 接收者为值或者指针
type B struct { thing int } /** 接收者类型为值 变量为值和指针时都可以调用,相当于传递了一个B类型的指针或者引用 */ func (b *B) change() { b.thing = 1 } /** 接收者类型为值 变量为值和指针时都可以调用,相当于传递了一个B类型的副本 */ func (b B) write() { b.thing = 2 } func main() { var b1 B // b1是值 b1.change() b1.write() fmt.Println(b1) b2 := new(B) // b2是指针 b2.change() b2.write() fmt.Println(b2) }
4. 内嵌类型的继承和方法
4.1 外层类型直接调用内嵌类型的方法
外层类型相当于继承了内嵌类型的方法;可通过 Outer.InnerMethod() 形式直接调用内嵌类型的方法
type Engine interface { Start() Stop() } type Car struct { Engine } func (c *Car) GoToWorkIn() { // get in car c.Start() // drive to work c.Stop() // get out of car }
4.2 外层类型和内嵌类型方法名冲突
方法名冲突时优先调用外层方法,可通过 Outer.Inner.Method() 调用内嵌类型的方法
type Point struct { x, y float64 } func (p *Point) Abs() float64 { return math.Sqrt(p.x * p.x + p.y * p.y) } type NamedPoint struct { Point name string } func (n *NamedPoint) Abs() float64 { return n.Point.Abs() * 100. } func main() { n := &NamedPoint{Point{3, 4}, "Pythagoras"} // 外层类型(Outer)方法和内嵌类型(Inner)方法名冲突时,通过Outer.Inner.methodName()调用Inner的method fmt.Println(n.Point.Abs()) // 打印5 // Outer.methodName()优先调用Outer的method fmt.Println(n.Abs()) // 打印500 }