Go中无传统指针数组,但可用切片或数组存储元素指针:先创建值再取地址;切片灵活推荐,数组适用于固定数量;须避免对字面量取址、循环变量复用及nil解引用。

在 Go 语言中,没有传统意义上的“指针数组”(如 C 中的 int* arr[5]),但可以通过切片或数组存储指向元素的指针,实现类似功能。关键在于:先创建底层值,再取地址存入指针容器。
用切片存储多个元素的指针(推荐)
切片灵活、可动态增长,适合大多数场景。需注意:不能直接对字面量取地址(如 &123),必须先有变量。
- 声明一个普通切片,元素类型为
*T(例如[]*int) - 逐个创建值变量,用
&v获取其地址并追加到切片 - 也可用循环批量初始化,避免重复写变量名
示例:
nums := []int{10, 20, 30, 40}
ptrs := make([]*int, len(nums)) // 预分配指针切片
for i := range nums {
ptrs[i] = &nums[i] // 取每个元素地址
}
// 此时 ptrs[0] 指向 nums[0],修改 *ptrs[0] 会影响 nums[0]
用数组存储固定数量的指针
当元素个数确定且不变化时,可用数组。语法为 [N]*T,例如 [3]*string。
立即学习“go语言免费学习笔记(深入)”;
- 数组长度必须是编译期常量
- 初始化时需确保每个指针都指向有效变量,不可为 nil(除非有意留空)
- 可使用复合字面量配合显式取址,但要避免临时变量生命周期问题
示例:
names := [3]string{"Alice", "Bob", "Charlie"}
ptrArr := [3]*string{
&names[0],
&names[1],
&names[2],
}
// 或更简洁地用循环赋值(因数组不可直接 range 赋值)
for i := range ptrArr {
ptrArr[i] = &names[i]
}
避免常见错误
初学者易踩的坑:
-
不要对字面量或函数返回值直接取地址:如
&"hello"或&fmt.Sprintf(...)是非法的,因为它们没有固定内存地址 -
注意循环中变量复用问题:在 for-range 中直接取
&v会导致所有指针指向同一个迭代变量的地址,应改用索引或新变量 -
nil 指针需检查:若指针未初始化就解引用(
*p),会 panic
实用技巧:快速初始化指针切片
封装成函数可提升复用性,尤其处理结构体指针时:
func intPtrs(values ...int) []*int {
ptrs := make([]*int, len(values))
for i, v := range values {
ptrs[i] = &v // 注意:这里 v 是副本,但取的是该副本地址,安全
}
return ptrs
}
// 使用:ptrs := intPtrs(1, 2, 3, 4)
注意:函数内 v 是参数副本,其地址在函数栈上有效;返回后仍可安全使用,Go 编译器会自动将其移到堆上(逃逸分析)。










