Go语言圣经 .5.方法

方法

方法声明

方法的声明和普通函数的声明类似,只是在函数名字的前面多了一个参数。这个参数把这个方法绑定到了这个参数对应的类型上。

示例:

package geometry

import "math"

type Point struct{X, Y float64}

// 普通的函数
func Distance(p, q Point) float64 {
return math.Hypot(q.X-p.X, q.Y-p.Y)
}

// Porint类型的方法
func (p Point) Distance(q Point) float64 {
return math.Hypot(q.X-p.X, q.Y-p.Y)
}

附加参数p成为方法的的接收者.

指针接收者的方法

由于主调函数会复制每一个实参变量,如果函数需要更新一个变量,或者一个实参太大而我们希望避免复制整个实参,我们就需要使用指针来传递变量的地址。这同样适用于更新接收者。

例如:

// 因为需要更新变量,使用指针
func (p *Point) ScaleBy(factor float64) {
p.X *= factor
p.Y *= factor
}

这个方法的名字是(*Point).ScaleBy

这里圆括号是必须的,没有括号,会被识别为*(Porint.ScaleBy)

命名类型(Point)和指向他们的指针(*Point)是唯一可以出现在接收者声明处的类型。而且,为了防止混淆,不允许本身是指针的类型进行方法声明

示例:

type P *int                                                                                                                                                                                                 func (p P) f() {/** ... **/}  //编译错误 invalid receiver type P (P is a pointer type)

nil也是一个合法的接收者

通过结构体内嵌组成类型

type Point struct { X, Y int}

type ColoredPoint struct {
Point
Color color.RGBA
}

使用互斥锁保护map的数据

type cache struct{
sync.Mutex
mapping map[string]string
}{
mapping:make(map[string]string),
}

func Lookup(key string) string {
cache.Lock()
v := cache.mapping[key]
cache.Unlock()
return v
}

方法变量与表达式

示例: 位向量

封装

如果变量或者方法是不能通过对象访问到的,这称作封装的变量或者方法。