关于go语言编译器自动解引用
-
用值类型的实参调用形参为值类型的方法
-
用指针类型的实参调用形参为值类型的方法(会进行“自动解引用”)
-
用值类型的实参调用形参为指针类型的方法(会进行“自动取引用”)
-
用指针类型的实参调用形参为指针类型的方法
我们还是用代码来说明问题。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26type node struct { Name string Next *node } // 用c语言翻译, // void Say(node* n) { printf("%dn", 123); } func (n *node) Say() { fmt.Println(123) } // 用c语言翻译, // void Say(node n) { printf("%dn", 123); } func (n node) Say2() { fmt.Println(2333) } func main() { n1 := &node{Name: "hui"} n1.Say() n1.Say2() // Say2()是值接收器 (*n1).Say2() go编译器为我们加上* 自动解引用 n2 := node{Name: "hui"} n2.Say() // Say()是指针接收器 (&n2).Say() go编译器为我们加上& 自动取引用 n2.Say2() }
记住两点
-
go语言只有值传递,指针也是值传递。
-
值类型接收器、指针类型接收器 可以理解为函数 的 一个形参。结合c语言如何做,对于c语言来说传值、传指针哪种会改变实参。
关键理解:当传递给方法的形参是一个值类型时(值类型接收器),原值的内容不会受到影响,因为值传递,传递进来的是原值的复制副本(形参是副本);相反,当方法的形参是一个指针类型时,原值的内容将可能受到影响,因为传递的是指针类型复制,虽然是复制但是指针中存储的地址仍然是实参的真实地址。
一个链表节点删除的例子
以链表节点删除问题为例,由于在go语言中都是参数都是值传递,所以在链表操作的时候不能直接操作形参来修改原来指针的内容,但可以修改其指向的内容为什么呢,用代码来解释
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34type node struct { Name string Next *node } func main() { n1 := &node{Name: "zgh"} n2 := &node{Name: "dev"} n3 := &node{Name: "devaaa"} n1.Next = n2 n2.Next = n3 n3.Next = nil ts(n2) data := make([]string, 0) for n1 != nil { data = append(data, n1.Name) n1 = n1.Next } fmt.Println(data) } func ts(n *node) { // 方式一: out: [hui dev devaaa] 不会删除 n = n.Next // 这里的n是一个指针的复制,此操作只会更改形参n指针的指向,不会更改实参的指向,如果想修改实参的指向,只能用方式二 // 方式二: out: [hui devaaa] //*n = *n.Next // 会更改实参,也就是被复制的指针 // 方式三: out: [hui asada] // 这种方式会更改实参,为什么呢 因为这里go语言的编译器会为你加上*来解引用 //n.Next= n.Next.Next // 实际(*n).Next= //n.Name = "asada" // 实际(*n).Name= }
最后
以上就是贪玩小蚂蚁最近收集整理的关于go 语言的自动解引用的全部内容,更多相关go内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复