Go数组是值类型、长度固定、类型明确的序列,声明即初始化并自动填充零值,长度须为编译期常量,不可用make初始化,支持字面量推导长度和索引初始化,从切片复制需用copy(dst[:], src)。

Go 语言中数组是值类型、长度固定、类型明确的序列,初始化方式直接决定其内存布局和使用安全边界——别用 make 初始化数组,那是切片的用法。
声明即初始化:零值自动填充
未显式赋值的数组会按元素类型填入零值(int 为 0,string 为 "",指针为 nil):
var a [3]int // [0 0 0] var b [2]string // ["", ""]
- 数组长度必须是编译期常量(不能是变量或函数返回值)
-
var a [n]T这种声明本身就会分配栈空间,不涉及堆分配 - 若元素类型较大(如含大结构体),直接声明可能引发栈溢出,需权衡
字面量初始化:显式指定值与长度
用大括号 {} 显式初始化时,长度可省略(由编译器推导),但不可混用「指定索引 + 非指定」以外的写法:
a := [3]int{1, 2, 3} // OK,长度 3
b := [...]int{1, 2, 3} // OK,长度自动为 3
c := [3]int{0: 1, 2: 3} // OK,等价于 [1 0 3]
d := [3]int{1, 2} // OK,末尾补零 → [1 2 0]
-
[...]T{...}是合法语法,但结果仍是数组(不是切片),cap()和len()相同 - 不允许写成
[3]int{1, 2, 3, 4}(越界编译错误) - 索引必须是常量且 ≤ 长度-1;
[3]int{4: 1}会报错:array index 4 out of bounds [0:3]
从切片复制:避免意外共享底层数据
数组无法直接从切片赋值,但可用循环或 copy 函数填充。注意:copy 不会自动扩容,只按目标长度或源长度取小值:
立即学习“go语言免费学习笔记(深入)”;
src := []int{10, 20, 30, 40}
var dst [3]int
copy(dst[:], src) // dst = [10 20 30],不会 panic
-
dst[:]转成切片后才能传给copy,这是唯一安全转接方式 - 若
src长度小于数组长度,剩余元素保持零值 - 绝不能写
dst = src(类型不匹配:cannot use src (type []int) as type [3]int)
数组在 Go 中容易被误当作切片来用,尤其在函数参数传递时——传数组是完整拷贝,传切片才是引用底层数组。初始化时多看一眼类型签名里的 [N]T 还是 []T,差一个符号,语义和性能天壤之别。










