关于指针这里

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

aznmoe

2020-03-12

老师你好,在下面这个函数中

func (q *Queue) Push(v int) {
	*q = append(*q, v)
}

参数 q 是一个 类型为 Queue 的指针类型变量,然后函数内部 对其进行操作。
我的问题是,就是在前面的章节中 老师你说过,go 语言是很灵活的,即如果一个方法其参数如果是指针,使用的时候会自动的 取值,就是是 3-1 章节最后演示的例子,我简化下如下:

package main

import "fmt"

func setValue(arr *[5]int) {
	// go 语言中 使用这个 指针 不用 (*arr)
	arr[1] = 11
	// 当然也可以 *arr 这样使用
	(*arr)[0] = 100
}
func main() {
	arr := [...]int{0, 1, 2, 3, 4}
	setValue(&arr) // !!!注意这里是问题2,最下面说这个问题了: setValue(arr) 为什么不行
	fmt.Println(arr)
}

即在 setValue 中 我可以直接使用 arr 而无需 *arr
那么问题一: 为什么在 push 函数中 我必须 *q 而不能直接 q = append(q, v)

问题二:在 4-1 章节 17:21 这个时间左右 老师讲 编译器很灵活,如果说一个方法 需要你传地址,那么你传值也是可以的即如下

pRoot := &root
pRoot.Print() 

// ======
func (node Node) Print() {
	fmt.Print(node.Value)
}

那么 setValue(arr) 为什么不行

写回答

1回答

ccmouse

2020-03-14

这个灵活性仅限于使用指针的时候

arr[0]与(*arr)[0]

pRoot.Print()与(*pRoot).Print()

这两个写法读起来差别很大,所以go允许我们简化写法,增加可读性。

传参的时候,我们写&arr和写arr,差别不大,反而写&arr更明确是传递了指针,所以go不允许我们在传参的时候混用。

我扩充一下后面这个pRoot.Print()的例子:

func (n Node) Print() {
}

func Print(n Node) {
}

pRoot := &root

pRoot.Print() // ok

Print(pRoot) // 编译错误

这两个Print函数其实在运行时是一样的。但是编译器因为上述的考量,允许写pRoot.Print,不允许写Print(pRoot)

2
1
aznmoe
emmm,希望老师 出一个视频 讲一下 什么情况下可以混用,什么情况下不能混用。我是前端开发,没有涉及到这里的知识,看视频的时候 发现前面可以混用 而 后面不可以 便非常懵。。希望老师考虑下。顺便 多谢~
2020-03-16
共1条回复

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

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

5995 学习 · 1909 问题

查看课程