在函数声明时,在其名字之前放上一个变量,即是一个方法。这个附加的参数会将该函数附加到这种类型上,即相当于为这种类型定义了一个独占的方法。
func (p Point) Distance(q Point) float64 {
return math.Hypot(q.X-p.X, q.Y-p.Y)
}
上面代码中的附加参数 p
,称为方法的接收器(receiver)。在Go语言中,我们并不会像其它语言那样用this或者self作为接收器;我们可以任意的选择接收器的名字。
这种p.Distance
的表达式叫做选择器,因为他会选择合适的对应p
这个对象的Distance方法来执行。选择器也会被用来选择一个struct类型的字段,比如p.X
。由于方法和字段都是在同一命名空间,所以如果我们在这里声明一个X
方法的话,编译器会报错,因为在调用p.X
时会有歧义。所以go中不允许“成员变量”和“成员函数”同名。
如果命名类型T(译注:用type xxx定义的类型)的所有方法都是用T类型自己来做接收器(而不是*T
),那么拷贝这种类型的实例就是安全的;调用他的任何一个方法也就会产生一个值的拷贝。
但是如果一个方法使用指针作为接收器(t *T),你需要避免对其进行拷贝,因为这样可能会破坏掉该类型内部的不变性。
但是使用*T的好处是,传递数据量比较小。因为只传了一个指针。
Go语言只有一种控制可见性的手段:大写首字母的标识符会从定义它们的包中被导出,小写字母的则不会。这种限制包内成员的方式同样适用于struct或者一个类型的方法。因而如果我们想要封装一个对象,我们必须将其定义为一个struct。
原文:https://www.cnblogs.com/Jun10ng/p/12820091.html