- 文档
- 教程
- 游戏开发
【免费下载链接】godot-docs
Godot Engine official documentation
Array 是 Godot 内置的核心容器类型,用于保存任意 Variant 元素的序列。本文以 class_array.rst 官方类参考为骨架,结合 GDScript 基础 与 C# 集合对照 等仓库资料,系统讲解 Array 的构造、索引、全部 49 个方法、运算符语义、类型化数组与压缩数组的取舍,以及遍历与复制时的注意事项,帮助你写出正确、高效、可维护的数组代码。
Array 是什么
Array 是一种内置数据结构,默认情况下可以容纳任意 Variant 类型的元素序列。通过创建typed array(类型化数组),可以将值约束为特定类型。元素通过从0开始的数值索引访问;负索引从尾部倒数(-1是最后一个元素,-2是倒数第二个,以此类推)。
var array = ["First", 2, 3, "Last"] print(array[0]) # Prints "First" print(array[2]) # Prints 3 print(array[-1]) # Prints "Last" array[1] = "Second" print(array[1]) # Prints "Second" print(array[-3]) # Prints "Second" # 这个类型化数组只能包含整数。 # 尝试添加任何其他类型都会报错。 var typed_array: Array[int] = [1, 2, 3]C# 中对应Godot.Collections.Array,索引语义一致(^1表示最后一个元素),类型化数组写作Godot.Collections.Array<int>:
Godot.Collections.Array array = ["First", 2, 3, "Last"]; GD.Print(array[0]); // Prints "First" GD.Print(array[2]); // Prints 3 GD.Print(array[^1]); // Prints "Last" array[1] = "Second"; GD.Print(array[1]); // Prints "Second" GD.Print(array[^3]); // Prints "Second" // 这个类型化数组只能包含整数。 Godot.Collections.Array<int> typedArray = [1, 2, 3];三个必须牢记的核心语义
1. 按引用传递
Array 总是按引用(reference)传递。如果你希望获得一个可独立于原数组修改的副本,必须使用duplicate()(详见"复制与切片"一节)。直接赋值var b = a只是让b与a指向同一个底层结构。
2. 迭代期间禁止删除元素
在遍历数组的同时擦除(erase)元素是不被支持的,会导致不可预测的行为。如果你需要在迭代中修改内容,官方建议改用for i in array.size()配合索引赋值(见 gdscript_basics.rst 的 for 循环说明)。
3. 布尔上下文中的求值规则
在布尔上下文中,空数组[]求值为false,非空数组始终求值为true。这在编写if my_array:这类条件判断时需要留意——它判断的是"是否为空",而不是"是否有某个元素"。
三种数组类型:压缩数组、类型化数组、非类型化数组
| 类型 | 迭代/修改速度 | 内存 | 灵活性 |
|---|---|---|---|
| 压缩数组(Packed Array) | 一般最快 | 最小 | 最低,缺少map()等便捷方法 |
| 类型化数组(Typed Array) | 较快 | 中等 | 中等,元素类型受限 |
| 非类型化数组(Untyped Array) | 较慢 | 较大 | 最高 |
原文档明确指出:压缩数组通常比同类型数组(如 PackedInt64Array 对比Array[int])迭代和修改更快、占用内存更少;其代价是灵活性低,不提供map()这类便捷方法。类型化数组又比非类型化数组迭代和修改更快。
gdscript_basics.rst 的 Packed arrays 小节 进一步补充了选型建议:
- 当数组足够大(成千上万个元素)且数据类型与某个
Packed类型匹配时,使用压缩数组可同时改善内存占用与迭代/修改性能; - 若数组规模不大(如远未达到数万元素),常规或类型化数组提供的便捷方法更利于编写和维护;
- 数据是已知类型(包括自定义类)时,优先使用类型化数组。
类型化数组的 GDScript 语法为Array[Type],Type可以是任意 Variant 类型、原生类、用户类或枚举;不支持嵌套数组类型(如Array[Array[int]])。Array与Array[Variant]等价。类型化数组的类型是内存结构的一个属性,因此不能把Array[Node2D]直接赋给Array[Node]变量(即使 Node2D 是 Node 的子类);需要转换时用assign()方法复制内容而非引用:
var a: Array[Node2D] = [Node2D.new()] # (OK) Node2D 继承自 Node,可以放入 Array[Node] var b: Array[Node] = [a[0]] # (Error) 不能将 Array[Node2D] 赋给 Array[Node] 变量 # b = a # (OK) 用 assign() 复制内容而不是引用 b.assign(a)唯一的例外是Array(即Array[Variant])类型,这是为兼容旧代码做的便利设计——但对非类型化数组的操作被视为不安全操作。另外注意,类型化数组目前在可变参数(variadic)函数中不受支持,无法写出...values: Array[int]。
构造函数
Array():构造空数组
构造一个空的 Array。
Array(base, type, class_name, script):从 base 构造类型化数组
从base数组创建类型化数组。类型化数组只能包含给定类型的元素,或继承自给定类的元素。参数含义:
type:内置 Variant 类型,取 Variant.Type 枚举常量之一;class_name:内置类名(参见 Object.get_class());script:关联的脚本,必须是 Script 实例或null。
如果type不是TYPE_OBJECT,则class_name必须为空StringName、script必须为null。
class_name Sword extends Node class Stats: pass func _ready(): var a = Array([], TYPE_INT, "", null) # Array[int] var b = Array([], TYPE_OBJECT, "Node", null) # Array[Node] var c = Array([], TYPE_OBJECT, "Node", Sword) # Array[Sword] var d = Array([], TYPE_OBJECT, "RefCounted", Stats) # Array[Stats]base数组的元素会在必要时进行转换。如果无法转换,或base本身已是类型化数组,则构造失败并返回空 Array。
在 GDScript 中通常不需要这个构造函数,静态类型即可创建类型化数组:
var numbers: Array[float] = [] var children: Array[Node] = [$Node, $Sprite2D, $RigidBody3D] # 浮点字面量会被转换为整数 var integers: Array[int] = [0.2, 4.5, -2.0] print(integers) # Prints [0, 4, -2]Array(from: Array):返回同一数组
返回与from相同的数组(引用,非副本)。需要副本请用duplicate()。
从压缩数组构造
Array(from: PackedByteArray)、Array(from: PackedColorArray)、Array(from: PackedFloat32Array)、Array(from: PackedFloat64Array)、Array(from: PackedInt32Array)、Array(from: PackedInt64Array)、Array(from: PackedStringArray)、Array(from: PackedVector2Array)、Array(from: PackedVector3Array)、Array(from: PackedVector4Array):分别从对应的压缩数组构造普通数组。这是压缩数组与普通数组互转的官方入口之一。
元素的增删改:核心增删方法
| 方法 | 签名要点 | 行为 |
|---|---|---|
append(value) | push_back()的别名 | 在数组末尾追加value |
append_array(array) | — | 将另一个array追加到本数组末尾 |
push_back(value) | — | 在末尾追加一个元素 |
push_front(value) | — | 在开头添加一个元素,会移动所有其他元素的索引,大数组上有明显性能开销 |
insert(position, value) | 返回 Error | 在position(可为负数,相对末尾)插入元素,返回OK或错误常量;position之后的索引都要前移,大数组开销明显 |
erase(value) | 按值删除 | 找到并移除value的第一次出现;不存在则什么都不做;删除后所有后续索引回移 |
remove_at(position) | 按下标删除 | 删除position处元素,负数相对末尾,越界会失败;需要返回值用pop_at(),按值删除用erase() |
pop_back() | 删除并返回 | 移除并返回最后一个元素;空数组返回null且不报错 |
pop_front() | 删除并返回 | 移除并返回第一个元素;空数组返回null且不报错;其余元素索引回移 |
pop_at(position) | 删除并返回 | 移除并返回position处元素,负数相对末尾;空数组返回null,越界会生成错误信息 |
clear() | 清空 | 移除所有元素,等价于resize(0) |
resize(size) | 调整大小 | 设为size个元素;缩小则删除末尾,扩大则添加默认元素(通常为null,取决于数组类型)。返回OK、ERR_LOCKED(只读数组)、ERR_INVALID_PARAMETER(size 为负)或ERR_OUT_OF_MEMORY。一次性resize后赋值比逐个append更快 |
fill(value) | 批量赋值 | 将value赋给所有元素;常与resize()组合使用 |
set(index, value) | 按下标赋值 | 与array[index] = value等价,不改变数组大小 |
assign(array) | 整体赋值 | 把另一数组的元素复制进本数组,按需 resize;类型化数组会执行类型转换 |
append_array示例:
var numbers = [1, 2, 3] var extra = [4, 5, 6] numbers.append_array(extra) print(numbers) # Prints [1, 2, 3, 4, 5, 6]resize+fill组合(GDScript 与 C# 对照):
var array = [] array.resize(5) array.fill(2) print(array) # Prints [2, 2, 2, 2, 2]Godot.Collections.Array array = []; array.Resize(5); array.Fill(2); GD.Print(array); // Prints [2, 2, 2, 2, 2]注意:如果
fill()的value是引用类型 Variant(继承自 Object、Array、Dictionary 等),数组会被填充为对同一个 value 的引用,而不是副本。
查询与搜索:find 系列与成员检查
| 方法 | 说明 |
|---|---|
size() | 返回元素个数,空数组返回0 |
is_empty() | 返回true当且仅当数组为空 |
has(value) | 返回是否包含value(GDScript 等价于in操作符;C# 中改名为Contains) |
count(value) | 返回value在数组中出现的次数;按条件计数请用reduce() |
find(what, from = 0) | 返回what第一次出现的索引,无则返回-1;from指定搜索起点 |
rfind(what, from = -1) | 返回what最后一次出现的索引,无则返回-1;find()的逆向版本 |
find_custom(callable, from = 0) | 返回第一个使callable返回true的元素索引,无则-1 |
rfind_custom(callable, from = -1) | 从后向前查找第一个满足callable的元素索引 |
front() | 返回第一个元素;空数组失败并返回null(与array[0]不同,只产生错误不中断项目执行) |
back() | 返回最后一个元素;空数组失败并返回null(与array[-1]不同) |
get(index) | 返回index处元素;越界或负索引失败并返回null。与[]操作符类似但不完全相同:失败时不会在编辑器中暂停项目执行 |
min() | 所有元素可比较时返回最小值,否则返回null |
max() | 所有元素可比较时返回最大值,否则返回null;自定义比较器可用reduce()实现 |
pick_random() | 返回随机一个元素;空数组报错并返回null |
hash() | 返回代表数组及其内容的 32 位哈希整数。哈希值相同的数组不一定相同(哈希碰撞),哈希值不同的数组必然不同 |
has()与in操作符示例:
print(["inside", 7].has("inside")) # Prints true print(["inside", 7].has("outside")) # Prints false print(["inside", 7].has(7)) # Prints true print(["inside", 7].has("7")) # Prints false if 4 in [2, 4, 6, 8]: print("4 is here!") # Will be printed.C# 对照(方法更名为Contains):
Godot.Collections.Array arr = ["inside", 7]; GD.Print(arr.Contains("inside")); // Prints True GD.Print(arr.Contains("outside")); // Prints False GD.Print(arr.Contains(7)); // Prints True GD.Print(arr.Contains("7")); // Prints False性能注意:出于性能考虑,
find()/has()的搜索会受到what的Variant.Type影响。例如7(int)和7.0(float)对这两个方法而言不相等。
find_custom配合bind()传递额外参数:
func is_even(number): return number % 2 == 0 func _ready(): print([1, 3, 4, 7].find_custom(is_even.bind())) # Prints 2 func is_specific_number(number, expected): return number == expected func _ready(): print([1, 3, 4, 7].find_custom(is_specific_number.bind(4))) # Prints 2函数式方法:map / filter / reduce / all / any
这四个方法是函数式编程风格的支柱,callable通常只接收当前数组元素一个参数(reduce例外,接收两个)。
map(callable):映射
对每个元素调用callable,返回由返回值组成的新数组。callable接收一个元素参数,可返回任意 Variant。
func double(number): return number * 2 func _ready(): print([1, 2, 3].map(double)) # Prints [2, 4, 6] # 同样效果,使用 lambda 函数 print([1, 2, 3].map(func(element): return element * 2))filter(callable):过滤
对每个元素调用callable,返回新过滤数组。callable返回true则保留该元素,false则排除。
func is_even(number): return number % 2 == 0 func _ready(): print([1, 4, 5, 8].filter(is_even)) # Prints [4, 8] # 同样效果,使用 lambda 函数 print([1, 4, 5, 8].filter(func(number): return number % 2 == 0))reduce(callable, accum = null):归约
对每个元素调用callable,将结果累积到accum并返回。callable接收两个参数:当前累积值accum和当前元素。若accum为null(默认),迭代从第二个元素开始,第一个元素作为accum的初始值。
func sum(accum, number): return accum + number func _ready(): print([1, 2, 3].reduce(sum, 0)) # Prints 6 print([1, 2, 3].reduce(sum, 10)) # Prints 16 # lambda 写法 print([1, 2, 3].reduce(func(accum, number): return accum + number, 10))reduce的三个高级用途——自定义比较器、按条件计数(替代count()):
# 自定义比较器:找出最长向量 func _ready(): var arr = [Vector2i(5, 0), Vector2i(3, 4), Vector2i(1, 2)] var longest_vec = arr.reduce(func(max, vec): return vec if is_length_greater(vec, max) else max) print(longest_vec) # Prints (3, 4) func is_length_greater(a, b): return a.length() > b.length() # 按条件计数 func is_even(number): return number % 2 == 0 func _ready(): var arr = [1, 2, 3, 4, 5] # 当前元素是偶数则计数加一,否则保持不变 var even_count = arr.reduce(func(count, next): return count + 1 if is_even(next) else count, 0) print(even_count) # Prints 2all(callable)与any(callable):全称与存在性判断
all():对所有元素调用callable,全部返回true才返回true;有一个以上返回false即返回false。any():至少一个元素使callable返回true即返回true;全部为false才返回false。
两者都支持 lambda。空数组语义不同:all()对空数组恒返回true(空真原则,vacuous truth),any()对空数组恒返回false。
func greater_than_5(number): return number > 5 func _ready(): print([6, 10, 6].all(greater_than_5)) # Prints true (3/3 个元素为 true) print([4, 10, 4].all(greater_than_5)) # Prints false (1/3 个元素为 true) print([4, 4, 4].all(greater_than_5)) # Prints false (0/3 个元素为 true) print([].all(greater_than_5)) # Prints true (0/0 个元素为 true) print([6, 10, 6].any(greater_than_5)) # Prints true (3 个元素为 true) print([4, 10, 4].any(greater_than_5)) # Prints true (1 个元素为 true) print([4, 4, 4].any(greater_than_5)) # Prints false (0 个元素为 true) print([].any(greater_than_5)) # Prints false (0 个元素为 true) # lambda 写法 print([6, 10, 6].all(func(element): return element > 5)) # Prints true print([6, 10, 6].any(func(number): return number > 5)) # Prints true性能提示:与"用
filter()结果的长度判断"相比,all()/any()会尽早返回以提升性能(尤其对大数组)。
排序
sort():升序排序
按元素的"小于"(<)比较升序排列。
var numbers = [10, 5, 2.5, 8] numbers.sort() print(numbers) # Prints [2.5, 5, 8, 10]Godot.Collections.Array numbers = [10, 5, 2.5, 8]; numbers.Sort(); GD.Print(numbers); // Prints [2.5, 5, 8, 10]注意:所用排序算法不稳定(not stable),等价元素(如
2与2.0)的相对顺序可能被改变。
sort_custom(func):自定义排序
func按需被调用,接收两个元素作为参数;返回true表示第一个元素应排在第二个之前,返回false则反之。
func sort_ascending(a, b): if a[1] < b[1]: return true return false func _ready(): var my_items = [["Tomato", 5], ["Apple", 9], ["Rice", 4]] my_items.sort_custom(sort_ascending) print(my_items) # Prints [["Rice", 4], ["Tomato", 5], ["Apple", 9]] # lambda 写法,降序 my_items.sort_custom(func(a, b): return a[1] > b[1]) print(my_items) # Prints [["Apple", 9], ["Tomato", 5], ["Rice", 4]]对文件名做自然顺序排序是sort_custom的典型场景,配合 String.naturalnocasecmp_to():
var files = ["newfile1", "newfile2", "newfile10", "newfile11"] files.sort_custom(func(a, b): return a.naturalnocasecmp_to(b) < 0) print(files) # Prints ["newfile1", "newfile2", "newfile10", "newfile11"]使用注意:C# 中不支持sort_custom;排序算法不稳定;不要随机化func的返回值——堆排序算法要求一致的结果,随机化会导致意外行为。
二分搜索
bsearch(value, before = true)
在已排序数组上使用二分查找返回value的索引;找不到时返回应插入以保持有序的位置。before为true(默认)时,返回的索引位于所有与value相等的既有元素之前。
var numbers = [2, 4, 8, 10] var idx = numbers.bsearch(7) numbers.insert(idx, 7) print(numbers) # Prints [2, 4, 7, 8, 10] var fruits = ["Apple", "Lemon", "Lemon", "Orange"] print(fruits.bsearch("Lemon", true)) # Prints 1, 指向第一个 "Lemon" print(fruits.bsearch("Lemon", false)) # Prints 3, 指向 "Orange"对未排序数组调用
bsearch()会产生意外结果,务必先sort()。
bsearch_custom(value, func, before = true)
与bsearch()相同,但用func做比较。func接收一个数组元素和value两个参数,返回true表示该数组元素应排在value之后。
func sort_by_amount(a, b): if a[1] < b[1]: return true return false func _ready(): var my_items = [["Tomato", 2], ["Kiwi", 5], ["Rice", 9]] var apple = ["Apple", 5] # "Apple" 插入到 "Kiwi" 之前 my_items.insert(my_items.bsearch_custom(apple, sort_by_amount, true), apple) var banana = ["Banana", 5] # "Banana" 插入到 "Kiwi" 之后 my_items.insert(my_items.bsearch_custom(banana, sort_by_amount, false), banana) # Prints [["Tomato", 2], ["Apple", 5], ["Kiwi", 5], ["Banana", 5], ["Rice", 9]] print(my_items)同样地,bsearch_custom要求数组已按func排序(可先用sort_custom(func)排序)。
复制与切片:duplicate / duplicate_deep / slice
duplicate(deep = false)
返回数组的新副本。默认浅拷贝:所有嵌套的 Array、Dictionary、Resource 元素与原数组共享,在一方修改会影响到另一方。deep为true时返回深拷贝:嵌套数组和字典被递归复制,但Resource 仍然共享。
duplicate_deep(deep_subresources_mode = 1)
类似duplicate(true)的深拷贝,但对子资源处理有额外控制。deep_subresources_mode必须是 Resource.DeepDuplicateMode 枚举的值;默认只递归复制内部资源。
slice(begin, end = INT_MAX, step = 1, deep = false)
返回包含从begin(含)到end(不含)元素的新数组,每隔step取一个。
begin/end为负时相对数组末尾;step为负时反向迭代,返回倒序切片(此时begin必须大于end);deep为true时递归复制切片中的嵌套 Array 与 Dictionary。
var letters = ["A", "B", "C", "D", "E", "F"] print(letters.slice(0, 2)) # Prints ["A", "B"] print(letters.slice(2, -2)) # Prints ["C", "D"] print(letters.slice(-2, 6)) # Prints ["E", "F"] print(letters.slice(0, 6, 2)) # Prints ["A", "C", "E"] print(letters.slice(4, 1, -1)) # Prints ["E", "D", "C"]只读与类型信息查询
| 方法 | 说明 |
|---|---|
is_read_only() | 返回数组是否为只读 |
make_read_only() | 将数组设为只读:元素不能被覆盖、顺序不能改变;不作用于嵌套元素(如字典)。GDScript 中声明为const的数组自动只读 |
is_typed() | 返回数组是否为类型化数组。类型化数组的方法仍返回通用 Variant |
is_same_typed(array) | 返回本数组与给定array的类型化方式是否相同 |
get_typed_builtin() | 返回类型化数组的内置 Variant 类型常量;非类型化返回TYPE_NIL |
get_typed_class_name() | 若内置类型为TYPE_OBJECT,返回类型化数组的内置类名;否则返回空 StringName |
get_typed_script() | 返回与该类型化数组关联的 Script 实例;不存在返回null |
var numbers: Array[float] = [0.2, 4.2, -2.0] print(numbers.is_typed()) # Prints true此外还有reverse()(反转所有元素顺序)与shuffle()(随机打乱元素顺序)。shuffle()与pick_random()一样使用全局共享随机种子;要获得可预测的结果,可先调用 @GlobalScope.seed()。
# 可能打印 1、2、3.25 或 "Hi" print([1, 2, 3.25, "Hi"].pick_random())运算符
| 运算符 | 返回 | 语义 |
|---|---|---|
array[index] | Variant | 按索引取元素,索引 0 起;负数从尾部取;越界访问会产生运行时错误,在编辑器中会暂停项目执行 |
array1 + array2 | Array | 拼接:把右侧数组追加到左侧,产生新数组。对已有数组,append_array()比+/+=更高效 |
array1 == array2 | bool | 长度与内容全部相等才为true |
array1 != array2 | bool | 长度或任一元素不同即为true |
<、<=、>、>= | bool | 从索引 0 起逐对比较,直到两个数组共同长度的末尾;逐对比较出大小即返回;若所有比较过的元素都相等,则由数组长度决定结果 |
运算符示例:
var array1 = ["One", 2] var array2 = [3, "Four"] print(array1 + array2) # Prints ["One", 2, 3, "Four"]C# 中注意,原生Array类型不支持拼接,但Godot.Collections.Array支持:
Godot.Collections.Array array1 = ["One", 2]; Godot.Collections.Array array2 = [3, "Four"]; GD.Print(array1 + array2); // Prints ["One", 2, 3, "Four"]遍历 Array:for 循环的正确姿势
gdscript_basics.rst 说明了遍历数组的两种方式:
var names = ["John", "Marta", "Samantha", "Jimmy"] for name: String in names: # 类型化循环变量 print(name) # 打印每个名字 # 如果要在迭代过程中赋值,最好用索引方式 for i in array.size(): array[i] = some_new_value(i)for x in [5, 7, 11]:会把元素依次存入x。注意原文档反复强调的规则:不要在遍历数组的同时 erase/pop 元素,否则行为不可预测。同时记住range()不会分配数组,纯数字循环应优先用for i in range(n)。
C# 中的 Array 与压缩数组映射
Collections 指南 指出:尽管名字是 "Array",Godot Array 更接近 C# 的List<T>而非System.Array,其大小不固定、可随增删动态伸缩。
- 未类型化的
Godot.Collections.Array可等价看作Variant元素数组,能容纳任意类型; - 泛型
Godot.Collections.Array<T>将元素类型限制为 Variant 兼容类型; - 未类型化数组可通过
new Godot.Collections.Array<T>(untypedArray)构造函数转换为类型化数组; - GDScript 的压缩数组在 C# 中直接使用
System.Array(byte[]、int[]、long[]、float[]、double[]、string[]、Vector2[]、Vector3[]、Vector4[]、Color[])。
由于 C# API 与 GDScript 存在差异,使用该 API 时请参考 C# 差异指南。例如has()在 C# 中更名为Contains,sort_custom()在 C# 中不受支持,Godot.Collections.Array的拼接也仅在 Godot 集合类型上可用。
实战选型建议与易错点清单
- 优先类型化:数据类型已知(含自定义类)时用
Array[Type],能获得更快的迭代/修改速度与编译期检查;静态类型分析 会考虑类型化数组约束。 - 大批量同质数据用压缩数组:达到成千上万个元素、且类型匹配
Packed*家族时,选择压缩数组换取内存与性能;需要map/filter等便捷方法时再转回普通数组。 - 副本用
duplicate:涉及嵌套结构修改时明确选择浅拷贝(默认)或深拷贝(deep=true/duplicate_deep),并牢记深拷贝仍共享 Resource。 - 插入/删除是 O(n) 操作:
push_front、insert、erase、remove_at、pop_front都会移动后续元素索引,大数组下应评估队列(Queue)或调整数据结构。 - 二分搜索前提是有序:
bsearch/bsearch_custom只对已排序数组可靠,且sort()/sort_custom()不稳定、sort_custom的比较器必须返回一致结果。 - 遍历期间不改动长度:需要增删时先收集索引或改用
for i in array.size()模式,避免不可预测行为。 - 区分类型敏感比较:
find/has受 Variant.Type 影响,7与7.0不相等;布尔上下文只区分空与非空。
参考资料
- Array 类参考(本文骨架源)
- GDScript 基础:容器类型、类型化数组与压缩数组
- GDScript 静态类型分析
- C# 集合指南:Array 与 PackedArray 映射
- C# 与 GDScript 的 API 差异
- 压缩数组类参考:PackedByteArray、PackedInt32Array、PackedInt64Array、PackedFloat32Array、PackedFloat64Array、PackedStringArray、PackedVector2Array、PackedVector3Array、PackedVector4Array、PackedColorArray
- 文档
- 教程
- 游戏开发
【免费下载链接】godot-docs
Godot Engine official documentation
相关推荐
Gel(EdgeDB)数组类型与数组函数完全指南:array 的构造、索引、切片与全部 std 数组函数
Gel(EdgeDB)数组类型与数组函数完全指南:array 的构造、索引、切片与全部 std 数组函数 数组(Array)是 Gel(EdgeDB)标准库中用
数据库图数据库关系型数据库Apache Druid SQL 数组函数(ARRAY Functions)完全指南:类型、语义与底层实现
Apache Druid SQL 数组函数(ARRAY Functions)完全指南:类型、语义与底层实现 本文聚焦 Apache Druid SQL 中针对
数据库OLAP大数据后端Apache Druid 数组类型(ARRAY)完全指南:摄入、过滤与分组实战
Apache Druid 数组类型(ARRAY)完全指南:摄入、过滤与分组实战 Apache Druid 支持 SQL 标准的 ARRAY 类型列,涵盖 VAR
数据库OLAP大数据后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考