Go语言——方法

Go语言——方法

Go语言作为一种类C的高级语言,在降低了C指针编程的门槛的同时,也增加了一些潜在的编程陷阱,甚至对于熟练使用Go语言的老手,也会不小心踩坑,本文对Go语言可能混淆的一些概念进行讨论,并辅以实例进行说明,同时也会总结Go语言编程的一些技巧。

方法定义

在声明函数时,在函数名前放上一个变量(可以称变量为接收器receiver),即声明了一个方法。我们通常定义一个结构体struct{},然后基于这个结构体定义一系列方法,实现面向对象中的类的概念。

接收器即可以是普通类型,也可以是指针类型。

此外,需要注意的是为避免歧义,在声明方法时,如果一个类型本身是一个指针的话,是不允许出现在接收器中的,比如下面这个例子:

我们也不能通过一个无法取地址的接收器来调用指针方法,比如临时变量的内存地址就无法获取得到:

方法也可以用指针作为其接收器:

方法调用陷阱

在调用方法时,Go编译器会根据我们定义方法的接收器,对变量做隐式转换。因此我们必须要注意,这种转换可能让我们的程序达不到我们预期想要的效果。熟悉C/C++的同学同学应该很容易明白值引用和指针引用的区别,这里我们总结一下,有如下四种情况:

结构体指针引用方法:会在方法内部改变该结构内部变量的值;

结构体值引用方法:在方法内部对变量的改变不会影响该结构;

对于结构体指针,如果调用的是值引用方法,不会改变结构内的变量值;

对于结构体值,如果调用的是指针引用方法,会改变结构体内的变量值;

提供一个完整的example.go例子如下:

运行结果如下:

可以看到:

是普通的对象,调用普通变量接收器的自增方法,并没有改变对象自身的值;

是指针对象,调用指针变量接收器的自减方法,对象自身的值被减一;

是普通的对象,调用指针变量接收器的自减方法,对象自身的值被减一;

是指针对象,调用普通变量接收器的自增方法,并没有改变对象自身的值;

扩展对象

类似于C++中的继承概念,我们在Go中,也可以将一个对象嵌入到另一个对象中,对对象进行扩展。扩展的对象也就能调用子对象中的方法

方法表达式

在调用接收器的方法时,我们通常的做法如下:

我们可以将此过程分为两步,首先得到方法的表达式也叫选择器:

然后再调用此方法表达式,此时不用传入接收器,可直接调用:

这两种对方法的调用方式是等价的。

至此,我们已经基本熟悉了方法使用中,可能会遇到的一些迷惑的地方,以及一些高级特性,基于此,我们可以实现出更为高效稳健的Go语言程序。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181028G15Y8900?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券