# 数组
数组是 Deft 的 可变 集合:一块扁平的值存储,通过 `aget` 和
`aset` 以 O(1) 复杂度进行索引读写。它们是对
集合中介绍的持久化集合的有意例外
——其他所有集合在更新时都返回新值,而数组就地修改。它们是标准库
原生函数,在每种宿主中都可用且无需导入,并显示为 `@{...}`。
热循环结束后,用 `collect` 将其转换回持久化列表。
## 函数
| 函数 | 用途 |
|---|---|
| `array values...` | 创建可变数组;当唯一参数为数字时,创建该长度的 nil 填充数组 |
| `array-of n v` | 预填充数组:一次分配中 `v` 的 `n` 份副本 |
| `aget arr i` | 读取从零开始的索引 `i` 处的元素(O(1)) |
| `aset arr i v` | 就地写入 `v` 到索引 `i`;返回该数组 |
说明:
- `[array 5]` 是长度为 5 的 nil 填充数组,不是 单元素数组。
只有当数字是唯一参数时才会被视作大小;`[array 5 6]` 保存 5 和
6 两个元素。
- `aget` 也接受向量(`@{...}`)。越界索引、负索引以及不可索引的
目标返回 `nil` 而不是抛出异常;字符串和映射不能用 `aget`
索引(请使用 `nth` / `get`)。
- `aset` 就地修改同一对象,并对数组和向量返回该对象;越界写入是
静默的空操作。非数字索引会引发
`%Err{:message expected number argument}`。`set-nth` 是返回新列表
的持久化替代方案。
- 数组不实现完整的集合协议;`collect` 可将数组转换为持久化列表。
## 示例
# Create def empty [array] # @{} def nils [array 5] # @{nil nil nil nil nil} def nums [array 1 2 3] # @{1 2 3} def zeros [array-of 4 0] # @{0 0 0 0} # Read [aget $nums 0] # => 1 $nums(aget 1) # => 2 (postfix form) [aget $nums 99] # => nil (out of range) # Mutate in place [aset $nums 1 99] # => @{1 99 3} [aget $nums 1] # => 99 [aset $nums 99 0] # out of range — silently ignored # Build a buffer in a loop def squares [array-of 4 0] for i in [range 0 4] { [aset $squares $i ($i * $i)] } $squares # => @{0 1 4 9} [collect $squares] # => @{0 1 4 9} (persistent list copy)