当切片的最大长度小于基础数组的长度时,术语“动态调整大小”如何合理?

时间:2019-12-08 12:55:06

标签: arrays go slice

来自A Tour of Go

  

数组的大小固定。另一方面,切片是对数组元素进行动态调整的灵活视图。

当切片不能超出基础数组的大小时,如何将其称为动态大小。

3 个答案:

答案 0 :(得分:3)

即使有上限,动态尺寸仍然是动态的:它的范围可以在零到上限之间。

也就是说,Flimzy noted in a comment的含义是,如果您使用可以“增长”切片的操作,则该操作始终会返回一个新切片,或获取指向该切片的指针(通常是前者),以便该例程需要超出当前容量的对象可以分配一个更大的新数组 1 ,并使片使用该数组而不是旧数组。

这就是append返回新值的原因,您必须输入:

s = append(s, element)

例如。

(如果以前的基础数组(如果有的话)在适当的时候被垃圾回收。nilslice没有基础数组,因此容量为零。)


1 运行时使用unsafe和其他特殊技巧来分配此数组,从而绕过类型检查,但与运行时自己的垃圾收集代码协调。因此,它可以分配其大小在运行时而不是在编译时选择的数组。编译器的newmakeappend内置程序可以访问此功能。

您可以使用unsafe自己编写这类棘手的代码,但是如果这样做,则可能会冒风险,如果新的Go版本发布了某些新的Go版本,则必须重写代码。内部。因此,不要这样做:使用appendmake创建具有已为您设置的切片数据的运行时大小的数组。

答案 1 :(得分:3)

Go数组的大小在编译时是固定的。 Go切片的大小在运行时动态设置。


参考文献:

The Go Blog: Go Slices: usage and internals

The Go Blog: Arrays, slices (and strings): The mechanics of 'append'

答案 2 :(得分:-1)

  

当切片不能超出基础数组的大小时,如何将其称为动态大小。

类型是静态的还是动态的。数组类型类似于[4]byte-大小是类型定义的一部分,因此在编译时进行设置。 [4]byte中只能存储[4]byte类型的变量。不是[3]byte,不是[5]byte。是静态的。

切片类型类似于[]byte-大小不是类型定义的一部分,因此它不是在编译时设置的,并且可以存储任何大小的切片在[]byte中运行。它可以是零长度,可以是一千,也可以是到一百万长度数组中的四字节窗口。它是动态的。

切片的大小也可以在运行时在其容量范围内缩小和增长,尽管容量只能通过替换基础数组(该数组为固定大小)来更改。例如,这是通过append在幕后自动完成的。但是,至少以我的理解,这不是使切片“动态”的原因。事实是,切片在运行时可以是任意大小-在编译时未知。那就是定义它们对我来说是“动态的”。