方法声明
type Point struct{ X, Y float64 }
func (p Point) Distance(q Point) float64 {
return math.Hypot(q.X-p.X, q.Y-p.Y)
}
基于指针对象的方法
func (p *Point) ScaleBy(factor float64) {
p.X *= factor
p.Y *= factor
}
这个方法的名字是(*Point).ScaleBy。这里的括号是必须的;没有括号的话这个表达式可能会被理解为*(Point.ScaleBy)。
r := &Point{1, 2}
r.ScaleBy(2)
fmt.Println(*r) // "{2, 4}"
或者这样:
p := Point{1, 2}
pptr := &p
pptr.ScaleBy(2)
fmt.Println(p) // "{2, 4}"
p := Point{1, 2}
(&p).ScaleBy(2)
fmt.Println(p) // "{2, 4}
这里的几个例子可能让你有些困惑,所以我们总结一下:在每一个合法的方法调用表达式中,也就是下面三种情况里的任意一种情况都是可以的:
要么接收器的实际参数和其形式参数是相同的类型,比如两者都是类型T或者都是类型*T:
Point{1, 2}.Distance(q) // Point
pptr.ScaleBy(2) // *Point
或者接收器实参是类型T,但接收器形参是类型*T,这种情况下编译器会隐式地为我们取变量的地址:
p.ScaleBy(2) // implicit (&p)
或者接收器实参是类型*T,形参是类型T。编译器会隐式地为我们解引用,取到指针指向的实际变量:
pptr.Distance(q) // implicit (*pptr)