首页 > 后端开发 > Golang > 正文

Golang slice与array的指针行为有什么差异_Golang底层内存结构对比

P粉602998670
发布: 2025-12-18 18:32:33
原创
183人浏览过
答案:Go中array是值类型,取地址得到指向其连续内存的指针,修改影响原数组且长度固定;slice是引用类型,取地址得到指向其头部结构体(含ptr/len/cap)的指针,该ptr才指向底层数组,多个slice可共享同一底层数组,修改元素相互可见,但append扩容后会断开共享;传参时[]T传递的是slice header副本,能修改底层数组内容但无法改变原slice变量指向,而[N]T传递整个数组副本,需传*[N]T才能修改原数组;关键在于指针所指目标不同:array指针直接指向数据块,slice变量本身是header值,其内部ptr才指向数据。

golang slice与array的指针行为有什么差异_golang底层内存结构对比

Go 中 slice 和 array 的指针行为差异,本质源于它们的底层内存结构不同:array 是值类型,直接持有固定长度的一段连续内存;slice 是引用类型,本身是轻量结构体(含指针、长度、容量),指向底层数组。这种设计导致“传指针”或“取地址”时的行为截然不同。

array 取地址得到的是整个数组的指针

对 array 变量使用 &a,得到的是指向该数组首元素的指针,类型为 *[N]T。这个指针直接关联整块内存,修改它所指向的内容会影响原数组,且无法通过该指针改变数组长度(长度是类型的一部分)。

例如:

var a = [3]int{1, 2, 3}
pa := &a // pa 类型是 *[3]int
pa[0] = 99 // a 变成 [99 2 3]

slice 取地址得到的是 slice 头部结构体的指针

对 slice 变量使用 &s,得到的是指向 slice 头部(header)的指针,类型为 *[]T,它指向的是包含 ptr/len/cap 三个字段的结构体本身,不是底层数组。

立即学习go语言免费学习笔记(深入)”;

这意味着:

Find JSON Path Online
Find JSON Path Online

Easily find JSON paths within JSON objects using our intuitive Json Path Finder

Find JSON Path Online 193
查看详情 Find JSON Path Online
  • 修改 (*s)[i] 会作用到底层数组,影响所有共享该底层数组的 slice
  • 但修改 *s(比如赋新 slice)只改变这个头部结构体的值,不影响其他变量
  • 若想让函数内重新 make 或切片操作反映到调用方,必须传 *[]T

底层数组才是真正的数据载体,slice 共享它

多个 slice 可以基于同一底层数组(如通过 s1 := s[1:3]),它们的 header 中 ptr 字段指向同一地址。此时:

  • 任意 slice 修改元素,其他 slice 都能看到(只要索引在各自 len/cap 范围内)
  • append 若触发扩容,会分配新底层数组,原 slice 的 ptr 就不再共享
  • array 没有“共享底层数组”的概念,复制就是完整拷贝

传参时的典型表现对比

函数参数是 []T 时,传的是 header 的副本(指针+长度+容量),所以能修改底层数组内容,但不能让调用方的 slice 变量指向新底层数组;而参数是 [N]T 时,传的是整个数组的副本,函数内修改不影响原数组 —— 除非你显式传 *[N]T

常见误区:以为 func f(s []int) { s = append(s, 1) } 能改变外部 slice,其实不能,因为 s 是 header 副本,append 后 s 指向新 header,原变量不变。

基本上就这些。理解关键不在“有没有指针”,而在“指针指哪儿”:array 的指针指数据块开头,slice 的指针(在 header 里)才指数据块开头,而 slice 变量自己只是 header 的值。

以上就是Golang slice与array的指针行为有什么差异_Golang底层内存结构对比的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号