Skip to content

紧缩数组

紧缩数组,又称压缩数组、打包数组,它们在迭代速度和内存占用方面相较于同类型的类型化数组Array有更大的优势,但代价是它们不够灵活,没有普通数组的便利方法,如Array.map()

紧缩数组的默认值为空数组[]

可以使用构造函数转换为普通数组,普通数组也可以通过构造函数转换为对应的紧缩数组

紧缩数组遍历的方式和普通数组相同,修改元素的方式与普通数组相同

可以使用==!=运算符比较数组长度与内容,而非引用

可以使用+=/+运算符来拼接数组

紧缩数组支持的类型有限:

声明/赋值

由于方括号[]在GDScript中表示普通数组,因此你需要使用以下方法来声明和赋值紧缩数组

显式指定类型

由于[]在不指定类型的情况下,默认为普通数组,因此你需要为紧缩数组的声明显式指定类型。

不同于类型化数组,赋值时不会进行元素的类型校验,与紧缩数组元素类型不一致的元素会尝试转换为对应类型,如果转换失败则替换为紧缩数组元素类型的默认值

gdscript
var arr : PackedInt32Array = [1, "2", 3, "", 5, Node.new()]
print(arr) # 输出 [1, 2, 3, 0, 5, 0]
var arr_1 = [1, 2, 3, 4]
var arr_2 : PackedInt32Array = arr_1 # 也可以直接将普通数组赋值给紧缩数组

使用构造函数

其实上面的语法等效于使用构造函数来声明或赋值数组,构造函数可以将普通数组转化为对应的紧缩数组

构造函数会尝试将数组中与紧缩数组元素类型不一致的元素转化为对应类型,如果转换失败使用紧缩数组元素类型的默认值

gdscript
var arr := PackedInt32Array([1, "2", 3, "", 5, Node.new()])
var arr_2 := ["", 1, 3, 4, 3.14, 1.25]
var arr_3 := PackedInt32Array(arr_2)
print(arr) # 输出 [1, 2, 3, 0, 5, 0]
print(arr_3) # 输出 [0, 1, 3, 4, 3, 1]

性能差异:PackedArray、类型化数组 和 非类型化数组

如果你要处理大量数据(比如几万个数值),PackedArray(如 PackedInt64Array会是最省内存、最快的选择

它在遍历和修改元素时的速度,比普通数组(包括 Array[int])还要快!

相比之下,普通数组(ArrayArray[int])提供了更多方便的方法,比如 map()filter() 等,PackedArray 就不支持这些

类型化数组(Array[int], Array[float] 等) 是普通数组的优化版:它们比未类型化的数组(Array)快,但不如 PackedArray 极致。

该怎么选择

如果你最关心的是性能,比如:

  • 处理大量数值

  • 数据类型是紧缩数组兼容的类型(intfloatString 等)

那就优先使用 对应的 PackedArray,既快又省内存。

如果你想要写代码更方便,喜欢用 map()filter() 等数组方法来处理数据 —— 哪怕性能差一点点也没关系,那就用 普通数组 Array类型化数组 Array[int]

如果你要存储自己定义的类(比如 MyItemMyNode 等),或者数据类型不确定,那就用 Array[YourType]。 这样可以兼顾可读性和性能。

练习

这一小节没有练习,但你可以尝试使用PackedInt32Array不转化为普通数组,来完成数组小节中除第1、3、4题以外的所有练习。