
go 语言中数组长度固定不可扩展,而切片才是动态可变的引用类型;要将固定长度数组传递给接受可变参数(...t)的函数,需通过 arr[:] 转换为切片。
go 语言中数组长度固定不可扩展,而切片才是动态可变的引用类型;要将固定长度数组传递给接受可变参数(...t)的函数,需通过 arr[:] 转换为切片。
在 Go 中,[3]int 和 []int 是两种完全不同的类型:前者是值类型、固定长度的数组,后者是引用类型、动态长度的切片。这决定了它们在使用方式上的根本差异。
- 数组
[n]T在声明时即确定长度,内存布局连续且大小固定,赋值时会整体拷贝; - 切片
[]T是对底层数组的轻量级封装,包含指向数组的指针、长度(len)和容量(cap),支持追加(append)、截取([:]) 等动态操作。
回到示例代码中的关键报错:
arr2 := [3]int{} // 类型为 [3]int
add(arr2...) // ❌ 错误:不能将 [3]int 直接作为 []int 传入可变参数这是因为 add(terms ...int) 的形参本质是 []int,而 arr2 是数组类型,Go 不允许隐式转换。正确做法是显式切片化:
add(arr2[:]...) // ✅ 正确:arr2[:] 生成一个 len=3、cap=3 的切片,指向 arr2 底层数据
arr2[:] 是切片操作的简写形式,等价于 arr2[0:len(arr2)],它不复制底层数组,仅创建一个新的切片头(slice header),因此高效且安全。
⚠️ 注意事项:
-
arr2[3] = 3在原代码中会导致 panic:index out of range [3] with length 3(索引从 0 开始,合法范围是 0~2); - 若需真正“扩容”,必须转为切片后使用
append(此时可能触发底层数组重新分配); - 数组转切片是零开销操作,但切片间的赋值仍为浅拷贝——修改切片内容会影响原数组(若未发生扩容)。
总结:Go 的类型系统严格区分数组与切片。当需要将数组用于接受 ...T 的函数、或进行动态操作时,务必使用 arr[:] 显式转为切片——这是理解 Go 内存模型与类型设计的关键一步。

















