如何在Go中分配非常量大小的数组

17

如何在 Go 中分配一个运行时大小的数组?

下面的代码是非法的:

 n := 1
 var a [n]int

当你看到类似 prog.go:12: invalid array bound n 的错误信息时,意味着有问题,与之相反,下面的代码运行正常:

 const n = 1
 var a [n]int

问题在于,我可能直到运行时才知道我想要的数组大小。

(顺便说一下,我首先在问题如何在Go中实现可调整大小的数组中寻找答案,但那是一个不同的问题。)

1个回答

22
答案是你不需要直接分配一个数组,当创建一个切片时,Go会为你分配一个。

内置函数make([]T, length, capacity)创建了一个切片和它背后的数组,并且对lengthcapacity的值没有(愚蠢的)编译时常量限制。正如Go语言规范中所说:

使用make创建的切片总是会分配一个新的、隐藏的数组,返回的切片值指向该数组。



因此我们可以写成:
 n := 12
 s := make([]int, n, 2*n)

并且分配一个大小为2*n的数组,使用s作为初始为其前一半的切片。

我不确定为什么Go不直接分配[n]int数组,因为你可以间接地实现它,但答案很清楚:“在大多数情况下,在Go中使用切片而不是数组。”


2
即使是反射包似乎也不允许分配动态大小的数组。我怀疑这与类型系统有关,因为数组大小是类型的一部分,所以动态大小需要动态生成新的类型标识符。 - Evan
1
@Evan 是的,尽管我避免使用“动态”来描述这个。严格来说,数组大小并不是动态的:一旦创建了数组,数组大小就是固定的。我想这与你无法访问切片后面的数组有关。如果可以访问,你就可以查看它的类型,这将不得不重新生成。这有某种意义。 - Steve Powell
我已经接受了自己的答案,因为它似乎是正确的。 - Steve Powell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接