Go中带固定长度如[3]int是数组,编译期定长、值传递、支持==比较;[...]int或[]int是切片,可扩容、传header、不支持==。二者类型不同,不可互赋,数组转切片需arr[:]。

Go 语言里数组不是切片,定义后长度就固定了
很多人一上来用 []int 写了个“数组”,结果发现能 append、能扩容——那其实是切片,不是数组。真数组必须写成 [3]int 这种带具体数字的形式,编译期就确定大小,内存连续且不可变长。
-
[5]string和[]string类型完全不同,不能互相赋值 - 函数传参时,
[3]int是值传递(整个数组拷贝),而[]int是传递 header(指针+长度+容量) - 如果只是临时存几个值、不打算增删,比如状态码映射:
[4]string{"OK", "Fail", "Pending", "Unknown"},用数组更轻量
初始化数组时省略长度只能用 ...,但只在特定上下文合法
写 arr := [...]int{1, 2, 3} 是可以的,编译器自动算出长度为 3;但这个 ... 只能在变量声明 + 字面量初始化时用,其他地方会报错。
- 不能写
var a [..]int或func foo([...]int)—— 都非法 - 不能对已声明的数组用
a = [...]int{1,2}赋值,因为左边类型是[3]int(假设之前声明的是[3]int),右边是新类型 - 如果想根据数据动态定长,老老实实用切片:
s := []int{1,2,3}
数组比较支持 ==,但切片不支持,别混着用
两个 [3]int 可以直接用 == 比较内容是否完全一致,这是 Go 唯一对数组的“友好”设计;换成 []int 就会编译失败。
- 错误示例:
if s1 == s2 { ... }(s1/s2 是[]int)→ 报错invalid operation: s1 == s2 (slice can only be compared to nil) - 正确做法:用
bytes.Equal(元素是 byte)或reflect.DeepEqual(通用但慢),或者自己循环比 - 注意:数组比较是逐元素值比较,不关心地址,所以
a := [2]int{1,2}; b := a; a == b是 true
把数组转成切片要用 arr[:],别漏冒号
想把一个数组当切片用(比如传给接受 []int 的函数),必须显式切一下:foo(arr[:])。只写 foo(arr) 会类型不匹配。
立即学习“go语言免费学习笔记(深入)”;
- 常见错误:写成
foo(arr[0:])或foo(arr[0:len(arr)])—— 虽然结果一样,但多此一举,arr[:]最简洁直观 - 如果只想传部分,比如前两个元素:
foo(arr[:2]),但注意不能越界(arr[:4]在[3]int上 panic) - 底层共享底层数组内存,修改切片内容会影响原数组 —— 这点和切片之间共享一样,不是数组特有


















