
go 语言不支持以运行时计算值作为数组长度,必须使用切片(slice)配合 make 创建动态长度的序列,这是实现如归并排序等算法的标准做法。
go 语言不支持以运行时计算值作为数组长度,必须使用切片(slice)配合 make 创建动态长度的序列,这是实现如归并排序等算法的标准做法。
在 Go 中,数组(array)是固定长度、值类型的底层数据结构,其长度必须是编译期可确定的常量(如 var buf [1024]byte 或 [len("hello")]rune)。因此,像 leftLength := middle - start + 1 这样依赖函数参数、在运行时才确定的表达式,无法用作数组长度——编译器会报错:non-constant array bound。
正确的替代方案是使用切片(slice),它底层引用一个数组,但自身是轻量级的引用类型,支持动态长度。通过 make([]T, len) 可直接分配指定长度的底层数组,并返回对应切片:
func merge(array []int, start, middle, end int) {
leftLength := middle - start + 1
rightLength := end - middle
left := make([]int, leftLength) // ✅ 正确:创建长度为 leftLength 的切片
right := make([]int, rightLength) // ✅ 同理
// 复制数据(示例)
copy(left, array[start:middle+1])
copy(right, array[middle+1:end+1])
// 后续合并逻辑...
}
⚠️ 注意事项:
- make([]int, n) 分配的是长度(len)和容量(cap)均为 n 的切片,无需额外扩容,性能高效;
- 切片不是链表,也不是自动扩容的“动态数组”(如 Java ArrayList),它只是对底层数组的视图;若需追加元素且超出容量,才触发 append 的扩容机制(此时才涉及内存复制);
- 在归并排序等场景中,每次 merge 调用都新建临时切片是常规且推荐的做法,Go 的垃圾回收器能高效管理这类短期对象。
总结:放弃用变量定义数组长度的想法,拥抱切片 —— 它是 Go 中处理动态尺寸数据的惯用、安全且高性能的方式。











