写点什么

Go 学习笔记之 方法

发布于: 27 分钟前
Go 学习笔记之 方法

方法声明

在函数声明时,在其名字之前放上一个变量,即是一个方法。这个附加的参数会将该函数附加到这种类型上,即相当于为这种类型定义了一个独占的方法。


在 Go 语言中,我们并不会像其它语言那样用 this 或者 self 作为接收器,我们可以任意的选择接收器的名字。

这里的建议是可以使用其类型的第一个字母,比如这里使用了 Point 的首字母 p。

package geometry
import "math"
type Point struct{ X, Y float64 }
// traditional functionfunc Distance(p, q Point) float64 { return math.Hypot(q.X-p.X, q.Y-p.Y)}
// same thing, but as a method of the Point typefunc (p Point) Distance(q Point) float64 { return math.Hypot(q.X-p.X, q.Y-p.Y)}
p := Point{1, 2}q := Point{4, 6}fmt.Println(Distance(p, q)) // "5", function callfmt.Println(p.Distance(q)) // "5", method call
复制代码

可以看到,上面的两个函数调用都是 Distance,但是却没有发生冲突。

  • 第一个 Distance 的调用实际上用的是包级别的函数 geometry.Distance;

  • 第二个则是使用刚刚声明的 Point,调用的是 Point 类下声明的 Point.Distance 方法。


基于指针对象的方法

当调用一个函数时,会对其每一个参数值进行拷贝,如果一个函数需要更新一个变量,或者函数的其中一个参数实在太大我们希望能够避免进行这种默认的拷贝,这种情况下我们就需要用到指针了。


对应到我们这里用来更新接收器的对象的方法,当这个接受者变量本身比较大时,我们就可以用其指针而不是对象来声明方法,如下:

func (p *Point) ScaleBy(factor float64) {    p.X *= factor    p.Y *= factor}
复制代码

这个方法的名字是(*Point).ScaleBy。这里的括号是必须的;没有括号的话这个表达式可能会被理解为*(Point.ScaleBy)


在现实的程序里,一般会约定如果 Point 这个类有一个指针作为接收器的方法,那么所有 Point 的方法都必须有一个指针接收器,即使是那些并不需要这个指针接收器的函数。我们在这里打破了这个约定只是为了展示一下两种方法的异同而已。

发布于: 27 分钟前阅读数: 2
用户头像

坚持分享接地气儿的架构技术文章! 2018.02.26 加入

同名微信公众号「架构精进之路」,专注软件架构研究,技术学习与职业成长!坚持原创总结、沉淀和分享,希望能带给大家一些引导和启发,感谢各位的支持(关注、点赞、分享)!

评论

发布
暂无评论
Go 学习笔记之 方法