如何使用Golang实现指针数组初始化_创建和赋值多元素指针

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

  • 数组长度必须是编译期常量
  • 初始化时需确保每个指针都指向有效变量,不可为 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 编译器会自动将其移到堆上(逃逸分析)。