Go关于切边变量本身地址和内部指向地址

复制代码
func main() {
	var a = []int{1, 2, 3, 4, 5}
	b := a                 //此时a,b都指向了内存中的[1 2 3 4 5]的地址
	b[1] = 10              //相当于修改同一个内存地址,所以a的值也会改变
	c := make([]int, 5, 5) //切片的初始化
	copy(c, a)             //将切片acopy到c
	c[1] = 52              //copy是值类型,所以a不会改变c
	fmt.Println(a, c)      // [1 10 3 4 5] [1 52 3 4 5]
	d := &a                //将a的内存地址赋值给d,取值用*d
	a[1] = 11
	fmt.Printf("d的值是%v,d的内存地址是%p\n", *d, d) //d的值是[1 11 3 4 5],d的内存地址是0xc420084060
	fmt.Printf("a的值是%v,a的内存地址是%p\n", a, &a) //a的值是[1 11 3 4 5],a的内存地址是0xc420084060
	fmt.Printf("b的值是%v,b的内存地址是%p\n", b, &b) //b的值是[1 11 3 4 5],b的内存地址是0xc000008060
}

对于上面代码中,a,b都指向了内存中的1 2 3 4 5的地址,为啥&a和&b不一样呢?

d却和a的指针一样?

关键概念区分

这里涉及到两个不同的地址:

  1. 切片变量本身的地址(&a、&b)
  2. 切片底层数组的地址(切片内部指向的数据)

图解说明:

具体解释:

第3行:b := a

  • a 和 b 是两个独立的切片变量(切片头),它们在栈上有不同的内存地址
  • 但它们内部的指针字段指向同一个底层数组 1, 2, 3, 4, 5
  • 所以 &a != &b(切片变量本身的地址不同)
  • 但修改 b1 会影响 a,因为它们共享底层数组

第9行:d := &a

  • d 是一个指向切片 a 的指针(类型是 *\[\]int)
  • d 存储的是 a 变量的地址,所以 d == &a
  • *d 解引用后得到的就是 a 这个切片

总结

核心要点

  • &a 和 &b 不同,因为它们是两个不同的变量
  • d == &a,因为 d 就是被赋值为 &a 的
  • a 和 b 共享底层数组,是因为它们的内部指针字段相同,而不是因为它们本身的地址相同
  • 这就是为什么Go的切片是引用语义:赋值时复制的是切片头(包含指针、长度、容量),但指针指向的是同一块底层数据。
相关推荐
鶴哥只手遮天1 分钟前
CFL3D深度解析:NASA经典CFD求解器的架构、算法与工程实践
算法
维克兜率天3 分钟前
【维克】价差交易实战:配对交易的核心参数设置
大数据·笔记·算法·量化
dtq04243 分钟前
数据结构 - 树的概念
c语言·数据结构·学习·算法
晒太羊的猫3 分钟前
hot100多维动态规划刷题
算法·动态规划
Dream it possible!8 分钟前
LeetCode_热题100_知识点总结
算法·leetcode·职场和发展
鶴哥只手遮天9 分钟前
从像素到战场:红外场景仿真引擎的核心技术深度解析
算法
anew___11 分钟前
《从零手写操作系统 (19):Ext2文件系统实战——从内存到磁盘的跨越》
java·服务器·前端·数据库·算法
盘古开天166613 分钟前
PPO算法原理详解(上):从策略梯度到近端策略优化的演进之路
人工智能·算法·机器学习·强化学习·ppo
云栈开源日记15 分钟前
机器人运动规划从A*到Minimum Snap四大算法全解析
算法·ai·机器人
H.莓飛17 分钟前
【数据结构】栈
linux·开发语言·数据结构·算法·centos