Go中没有独立的“指针数组”类型,但可声明元素为指针的数组如[3]int,其长度固定、属值类型,与动态切片[]int在内存布局、语义和使用上本质不同。
什么是 Go 中的指针数组?
Go 没有“指针数组”这个独立类型,但你可以声明一个「元素类型为指针」的数组,比如 [3]*int。它和 []*int(切片)在内存布局、长度语义和使用方式上完全不同——不是语法糖,而是两种结构。
关键区别在于:数组长度固定且是类型的一部分;切片是动态视图,底层依赖底层数组和三个字段(ptr, len, cap)。
[N]*T 数组的声明与初始化要小心
声明 [2]*string 后,每个元素初始值是 nil,不能直接解引用。常见错误是忘记分配内存就写 *arr[0] = "hello",会 panic:invalid memory address or nil pointer dereference。
- 必须先为每个指针分配目标值:
arr[0] = new(string); *arr[0] = "a" - 或用取地址操作:
s := "b"; arr[1] = &s - 数组字面量可内联初始化:
arr := [2]*string{new(string), new(string)}
为什么不用 []*T 切片代替指针数组?
多数场景下该用切片。数组适合编译期确定大小、需值语义传递(如作为 map key 或 struct 字段)、或对接 C 时对齐内存布局。切片更灵活,但要注意:即使元素是指针,append 可能导致底层数组重分配,原指针仍指向旧地址,但内容未变——这本身不危险,但若误以为切片扩容会影响已有指针目标,就容易逻辑错乱。