关于Queue的疑问

来源:4-3 扩展已有类型

慕容3506161

2021-02-17

前面章节中讲解slice操作的时候,使用append函数好像并没有需要加上*,为什么这里queue又需要加上*

写回答

1回答

ccmouse

2021-02-21

[]int类型里包括了底层数组的地址,slice的起始位置,slice的长度等。[]int本身是不可变的。

我们比较:

var q []int

q=append(q, v)

由于[]int不可变,append(q,v)本身不会改变q,所以它需要返回一个新的slice,这个新的slice就在等号左边,只不过我们还是用q这个变量来接。

而在Queue这个类型实现的时候,我们相当于做了

var q *[]int

*q=append(*q,v)

q是一个指针,运行append的时候,旧的*q不会改变,但生成了一个新的[]int,我们用*q去接。在运行append前后,q这个指针变量是同一个变量,但它的值,是一个[]int类型的地址,它变了。

我们在实现Queue类型

var q Queue

q.push(3)

要的就是q还是这个q,但是底层的slice在push处被改变的行为,因此使用指针的形式。


另一个角度看,可以公式化的理解:为结构体/类型定义方法,如果这个方法改变了结构体/类型,那么在接收者处就使用指针。

0
2
ccmouse
回复
Broase
我们这个函数的定义是,假如不用指针: func (q Queue) push(v int) 接收者q其实就是一个函数的参数,它采用拷贝的方式进行传参。 q=append(q,v)运行后,函数内的q的确被改变了。但是调用的地方, q.push(3),这个q没有被改变。因此在函数外,push完之后, q还是原来的q。 同学可以试一下连续push多个值进去,看看是不是我说的这样。可以在函数内和函数外分别打印q所对应的内容。
2021-03-17
共2条回复

Google资深工程师深度讲解Go语言 由浅入深掌握Go语言

语法+分布式爬虫实战 为转型工程师量身打造

5995 学习 · 1909 问题

查看课程