测试 Golang 指针变量的引用传递

首先设计一个数据结构(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}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值