大家好,我是编程小6,很高兴遇见你,有问题可以及时留言哦。
在面向对象编程中,一般将抽象的东西称为类。在Go语言中没有类对应的东西,因此用结构体来抽象。因此可以说,在Go语言中,类就是结构体,结构体就是类(后面我们统一都采用类的说法)。
类主要由两部分组成,一是属性,比如一辆车的品牌,外观,引擎等,二是行为,表示类所拥有的动作,比如车可以拐弯,加速,刹车等。
首先,我们定义一个猫类,如下:
//定义猫类
type Cat struct {
age int
}
这里我们简单的抽象一个属性就是年龄,接着就可以给猫绑定几个方法。在Go语言中称为给“接收器”绑定几个方法,接收器一共有两种,1. 实例接收 2. 指针接收
一、为猫类添加setAge方法,使用实例接收
//设置猫的年龄
func (c Cat) setAge(a int) {
c.age = a
}
有些同学不理解这个,我们可以换另一种方式理解。先将setAge就当作是一个普通的函数,只不过在形参中将实例安插进来,如下:
这样看就一下理解了,我们可以认为两者是等价的。
二、为猫类添加setAge方法,使用指针接收
//设置猫的年龄
func (c *Cat) setAge(a int) {
c.age = a
}
同理,它也等价于下面的普通函数调用
func setAge(c *Cat, a int) {
c.age = a
}
首先,我们给出两条结论:
也就是说,不管实例或者指针,都可以调用该类的任何方法,只不过在具体调用过程中会发生转换,我们重点看下不同的调用。
一、基础类型调用指针接收器的方法
//定义猫类
type Cat struct {
age int
}
//设置猫的年龄
func (c *Cat) setAge(a int) {
c.age = a
}
func main() {
var cat = Cat{
age: 2,
}
//基础类型调用指针的方法
cat.setAge(3)
fmt.Println(cat.age)
}
根据前面的推导,我们知道,指针接收器的方法就是指针做为形参的函数调用,既然需要的是指针,按照逻辑,应该传过去的是实例的地址。
因此,Go语言会将cat转换为&cat传过去,结果就是将原来猫的年龄修改了。
二、指针调用基础类型接收器的方法
//定义猫类
type Cat struct {
age int
}
//设置猫的年龄
func (c Cat) setAge(a int) {
c.age = a
}
func main() {
var cat = &Cat{
age: 2,
}
//指针调用基础类型的方法
cat.setAge(3)
fmt.Println(cat.age)
//打印2
}
根据推导,基础类型接收器的方法就相当于实例做为形参的函数调用,既然需要的是实例,而这里调用的指针,按照逻辑,应该传过去的是该指针指向值的副本。
因此,Go语言会将cat取值复制一份过去,也就是*cat复制一份,这样一只猫变成两只猫,方法修改的是副本的值,原值不会变化。
一、实例可以调用类的任何方法
二、指针可以调用类的任何方法
三、用实例值或指针类型调用方法时,编译器会自动在基础类型和指针类型之间转换