方法

118 阅读1分钟

方法声明

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)