登录
首页 >  Golang >  Go教程

Golang数组指针传递技巧解析

时间:2026-01-22 08:30:47 323浏览 收藏

在IT行业这个发展更新速度很快的行业,只有不停止的学习,才不会被行业所淘汰。如果你是Golang学习者,那么本文《Golang数组指针传递方法详解》就很适合你!本篇内容主要包括##content_title##,希望对大家的知识积累有所帮助,助力实战开发!

因为Go中数组是值类型,传参时会复制整个数组,函数内修改不影响原数组;需用数组指针(*[3]int)或切片([]int)才能修改原数据。

如何在Golang中修改数组需要使用指针_Golang数组指针传递技巧

为什么直接传数组无法修改原数组

Go 语言中,array 是值类型。当你把一个数组(比如 [3]int)作为参数传给函数时,实际上传的是整个数组的副本。函数内部对它的任何修改,都不会影响调用方的原始数组。

常见错误现象:

func modify(arr [3]int) {
    arr[0] = 999
}
a := [3]int{1, 2, 3}
modify(a)
// a 还是 [1 2 3],没变

这不是 bug,是 Go 的设计选择:数组大小固定、可比较、适合栈上分配。但这也意味着——想改原数组,必须绕过值拷贝。

用指针传递数组:明确指定长度和类型

最直接的方式是传指向数组的指针,比如 *[3]int。这时函数接收的是地址,解引用后可直接写原内存。

  • 必须写明数组长度([3]),因为 [3]int[4]int 是完全不同的类型
  • 调用时需用 &a 取地址,不能漏掉 &
  • 函数内通过 (*arr)[i] 或更常见的 arr[0](Go 允许对数组指针直接下标访问)操作

实操示例:

func modifyPtr(arr *[3]int) {
    arr[0] = 999 // 等价于 (*arr)[0] = 999
}
a := [3]int{1, 2, 3}
modifyPtr(&a)
// a 现在是 [999 2 3]

更常用的是切片:隐式指针 + 灵活长度

绝大多数场景下,你真正需要的不是“修改固定长度数组”,而是“修改一段连续数据”。这时应优先用 []int(切片),它底层包含指向底层数组的指针、长度和容量。

切片是引用类型(本质是结构体,含指针字段),传参时只拷贝这个小结构体,不影响语义上的“可修改原数据”。

  • 函数签名更简洁:func modifySlice(s []int),无需写死长度
  • 调用方直接传 a[:](从数组转切片)或原生切片变量
  • 注意:仅修改元素值可生效;但 append 可能导致底层数组扩容,此时原数组不受影响

示例:

a := [3]int{1, 2, 3}
modifySlice(a[:]) // 传切片视图
// a 被修改了

func modifySlice(s []int) {
    if len(s) > 0 {
        s[0] = 999 // ✅ 影响原数组
    }
}

容易踩的坑:混淆数组指针和切片,以及越界行为

新手常把 *[3]int 当成“类似 C 的 int*”,结果发现不能用 len()、不能遍历、甚至传错类型。

  • *[3]int 不是切片,不能直接用 range,也不能调用 len()cap() —— 必须先解引用:len(*arr)
  • 误写成 func f(arr *[3]int) 却传 &[]int{1,2,3}:类型不匹配,编译失败
  • 用切片时以为 append 总是修改原数组:其实当容量不足时会分配新底层数组,原数组不变
  • 数组指针在结构体字段中要小心:type T struct { Data *[1024]byte } 会把整个 1KB 数组塞进结构体,通常应改用 []byte*[1024]byte 配合 make 分配

复杂点在于:Go 没有“动态数组”原生类型,数组和切片语义分离。选哪种,取决于你是否需要编译期长度检查、是否涉及 cgo、是否追求极致栈分配——大多数业务代码,用切片就够了,别硬套数组指针。

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

前往漫画官网入口并下载 ➜
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>