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 可能导致底层数组重分配,原指针仍指向旧地址,但内容未变——这本身不危险,但若误以为切片扩容会影响已有指针目标,就容易逻辑错乱。
本文档主要讲述的是Sencha touch 开发指南;主要介绍如何使用Sencha Touch为手持设备进行应用开发,主要是针对iPhone这样的高端手机,我们会通过一个详细的例子来介绍整个开发的流程。 Sencha Touch是专门为移动设备开发应用的Javascrt框架。通过Sencha Touch你可以创建非常像native app的web app,用户界面组件和数据管理全部基于HTML5和CSS3的web标准,全面兼容Android和Apple iOS。希望本文档会给有需要的朋友带来帮助;感兴趣的
立即学习“go语言免费学习笔记(深入)”;
-
[]int和[]*int的append行为一致:只影响切片头,不影响指针所指内存 - 若需稳定地址(例如多个 goroutine 共享同一堆变量),应确保被指向的对象生命周期足够长,而不是依赖切片是否扩容
- 函数参数传
[3]*int是复制整个数组(含 3 个指针值);传[]*int只复制切片头(24 字节),更轻量
指针数组和切片在反射与序列化中的表现差异
JSON 编码时,[2]*string 会编码成 JSON 数组,但 nil 指针变成 null;而 []*string 同样如此,表面看不出区别。真正差异在反射:reflect.TypeOf([2]*string{}) 返回的是 Array 类型,Kind() 是 Array;切片则是 Slice。如果你写通用序列化适配逻辑(比如 ORM 字段映射),必须显式区分二者,否则 reflect.Value.Len() 对数组合法,对切片也合法,但 Cap() 对数组 panic。
- 检查是否为数组:
v.Kind() == reflect.Array - 获取长度统一用
v.Len(),但只有切片支持v.Cap()和v.Append() - 从
interface{}反解时,类型断言要精确:v.([3]*int)和v.([]*int)完全不同









