Go语言没有复杂的
class
概念,严格来说不是面向对象的语言,她和C语言
很像,是面向函数的;Go中函数用关键字func
来声明。Go没有class
但是有struct、interface
,可以把他们理解成类型定义;问题来了,有一种用func
声明的函数可以指定struct、interface
类型的接收者,这种函数在Go语言中单独叫做方法
;方法的接收者可以是一个类型的值也可以是一个类型的引用(指针)。
对Go语言数据类型的整体认识,可以参考以前的文章:Go学习(一)数据类型的本质
值接收者和指针接收者
- 方法的接收者是某类型的值变量,称为值接收者方法
- 方法的接收者是某类型的指针变量,称为指针接收者方法
下面我们来做一个实验,先定义一种鸭子(几条腿,是否会飞,是否能游泳),然后为鸭子类型声明两个方法,方法的作用一样都是设置鸭子有几条腿;只不过一个是值接收者,一个是指针接收者:
1 | type Duck struct { |
大家猜一猜执行ShowMeTheLegs()
函数,打印的结果是啥?很简单,就是下面结果:
1 | 1. First duck legs: 0 |
结论
第一:变量first是一个值变量,second是一个指针变量,结果他们都可以调用值接收者和指针接收者声明的方法。
第二:值接收者方法修改的值并不改变调用者,指针接收者方法修改的值改变了调用者。
无论是类型的值或指针,在调用指针接收者方法或值接收者方法时,编译器都对他们做了相应的转换,所以互相混着调用都能成功。之间的关系就如上图所示。
但是接口的变量却不能随意混合调用值接收者方法和指针接收者方法,这一话题我们放在以后接口和方法集单独讨论。