2.12. 数组
数组是由从 0 到数组大小减 1 的整数索引的值序列。数组的元素可以通过其索引获得:
var a = fixed_array<int>(1, 2, 3, 4) // 数组的固定大小为 4,内容为 [1, 2, 3, 4] assert(a[0] == 1)
var b: array<int> push(b,1) assert(b[0] == 1)
替代语法为:
var a = fixed_array(1,2,3,4)
有静态数组(固定大小,在堆栈上分配)和动态数组(大小是动态的,在堆上分配):
var a = fixed_array(1, 2, 3, 4) // 数组的固定大小为 4,内容为 [1, 2, 3, 4]
var b: array<string> // 空动态数组
push(b, "some") // 现在是 包含“some” 的 1 个元素的数组
b |> push("some") // 与上述行相同,但使用 Pipe 运算符
可以通过范围索引从任何数组类型创建动态子数组:
var a = fixed_array(1,2,3,4)
let b <- a[1..3] // b 是 [2,3]
实际上,a[b],其中 b 是一个范围,等效于`subarray(a, b)`。
动态数组和数组元素的大小调整、插入和删除是通过一组标准函数完成的(参见 built-in functions).
相关的内置函数是: push
, push_clone
, emplace
, reserve
, resize
, erase
, length
, clear
, empty
和 capacity
.
数组(以及 table、structures 和 handled 类型)仅通过引用传递给函数。
数组无法复制;Only Cloned (仅克隆) 或 Moved (移动)。
def clone_array(var a, b: array<string>)
a := b // a 不是 b 的深层副本
clone(a, b) // 同上
def move_array(var a, b: array<string>)
a <- b // a 不指向与 b 相同的数据,b 为空。
数组可以内联构造:
let arr = fixed_array(1.,2.,3.,4.5)
这扩展到:
let arr : float[4] = fixed_array<float>(1.,2.,3.,4.5)
动态数组也可以内联构造:
let arr <- ["one"; "two"; "three"]
这在语法上等同于:
let arr : array<string> <- array<string>("one","two","three")
替代语法为:
let arr <- array(1., 2., 3., 4.5)
let arr <- array<float>(1., 2., 3., 4.5)
结构数组可以内联构造:
struct Foo {
x : int = 1
y : int = 2
}
var a <- array struct<Foo>((x=11,y=22),(x=33),(y=44)) // 具有 'construct' 语法的 Foo 的动态数组(创建 3 个不同的 Foo 副本)
可以内联构造变体数组:
variant Bar {
i : int
f : float
s : string
}
var a <- array variant<Bar>(Bar(i=1), Bar(f=2.), Bar(s="3")) // Bar 的动态数组(创建 Bar 的 3 个不同副本)
可以内联构造元组数组:
var a <- array tuple<i:int,s:string>((i=1,s="one"),(i=2,s="two"),(i=3,s="three")) // 元组的动态数组(创建 3 个不同的元组副本)
当数组元素无法复制时,使用 push_clone
插入一个值的克隆,或者使用 emplace
将其移入。
resize
可能会创建新的数组元素。这些元素初始化为 0。
reserve
存在是出于性能原因。通常,如果超过,数组容量会加倍。
reserve
允许您指定确切的已知容量,并显著减少多个 push
作的开销。
empty
告诉你动态数组是否为空。
clear
清除数组,但不释放内存。它等价于 resize(0)
。
length
返回数组中的元素数。
capacity
返回无需重新分配即可存储在数组中的元素数。
可以通过常规的 for
循环遍历数组。
for ( x in [1,2,3,4] ) {
print("x = {x}\n")
}
此外,还提供了一组不安全的迭代器:
def each ( a : auto(TT)[] ) : iterator<TT&>
def each ( a : array<auto(TT)> ) : iterator<TT&>
两者都是不安全作的原因是它们不会捕获数组。
搜索函数可用于静态和动态数组:
def find_index ( arr : array<auto(TT)> implicit; key : TT )
def find_index ( arr : auto(TT)[] implicit; key : TT )
def find_index_if ( arr : array<auto(TT)> implicit; blk : block<(key:TT):bool> )
def find_index_if ( arr : auto(TT)[] implicit; blk : block<(key:TT):bool> )