首先设计一个数据结构(Golang 结构体) SimpleList :
type SimpleList struct {
num int
next *SimpleList
}
num 用来代表该结构的编号。
*SimpleList 用来表示该结构体类型的指针变量,指向下一个节点。
创建头节点 head。
创建其它节点 node1、node2、node3。
node3 := &SimpleList{
num: 3,
}
node2 := &SimpleList{
num: 2,
next: node3,
}
node1 := &SimpleList{
num: 1,
next: node2,
}
head := &SimpleList{
next: node1,
}
fmt.Println("head:", head)
fmt.Println("node1:", node1)
fmt.Println("node2:", node2)
fmt.Println("node3:", node3)
输出结果:
head: &{0 0xc000044210}
node1: &{1 0xc000044200}
node2: &{2 0xc0000441f0}
node3: &{3 <nil>}
创建一个临时节点 temp,把 head 赋值给临时节点 temp。
移除 temp 的下一个节点,即让 temp 直接指向下下一个节点,同时,直接输出 head.next。
观察:head.next 是指向 head 的下一个节点,还是指向 head 的下下一个节点?
temp := head
temp.next = temp.next.next
fmt.Println("head.next:", head.next)
输出结果:
head.next: &{2 0xc0000441f0}
我们可以发现,head.next 并没有指向1号节点( head 节点的下一个节点),而是经过 temp 节点的操作后(temp.next = temp.next.next)
指向了下下一个节点(2号节点)
那么,为什么 head 赋值给 temp 后,在 temp 中的操作会影响到 head 呢?
因为发生了引用传递,我们用示意图来分析:
如上图所示:
head 为 *SimpleList 类型的指针,指针变量内存放的具体内容为:
&{0 0xc000044210}
然而,存放地址的指针变量 head 同样也有自己的地址,head 的地址为:
0xc000006028
当我们把 head 赋值给 temp,实际上发生了如下的操作:
有一个新的指针变量 temp 存储了和 head 一样的内容:
&{0 0xc000044210}
经过 temp.next = temp.next.next 的操作后,说明 &{0 0xc000044210} 该地址内容代表的节点,指向了下下一个节点。
无论是变量 temp 还是变量 head,指向的同样都是内容为 &{0 0xc000044210} 的节点。
因此无论变量 temp 对该节点做了什么修改,用变量 head 再次指向该节点的时候,修改都会生效。
因此,我们后续再使用 head 变量来访问该内容的时候,该内容已经指向了节点 2 。
因此当我们直接输出 head 的下一个节点,输出的不是节点 1 ,而是节点 2。
完整代码如下:
/*
测试 Golang 指针变量的引用传递
*/
package main
import "fmt"
type SimpleList struct {
num int
next *SimpleList
}
func main() {
node3 := &SimpleList{
num: 3,
}
node2 := &SimpleList{
num: 2,
next: node3,
}
node1 := &SimpleList{
num: 1,
next: node2,
}
head := &SimpleList{
next: node1,
}
fmt.Println("head:", head)
fmt.Println("node1:", node1)
fmt.Println("node2:", node2)
fmt.Println("node3:", node3)
temp := head
temp.next = temp.next.next
fmt.Println("head.next:", head.next)
fmt.Println("指针变量 head 的地址为:", &head)
fmt.Println("指针变量 temp 的地址为:", &temp)
fmt.Println("指针变量 head 的值为:", head)
fmt.Println("指针变量 temp 的值为:", temp)
}
输出结果:
head: &{0 0xc000044210}
node1: &{1 0xc000044200}
node2: &{2 0xc0000441f0}
node3: &{3 <nil>}
head.next: &{2 0xc0000441f0}
指针变量 head 的地址为: 0xc000006028
指针变量 temp 的地址为: 0xc000006038
指针变量 head 的值为: &{0 0xc000044200}
指针变量 temp 的值为: &{0 0xc000044200}