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, emptycapacity.

数组(以及 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> )