列表与数组
DScript 列表与其他编程语言中所谓的数组非常相似。然而,存在差异。在大多数其他语言中,你必须先声明数组才能使用它。例如,如果你想使用包含十个数字的数组,你首先声明数组并指定其大小。然后编程语言分配一个足够容纳所有十个数字的单个内存块。在 DScript 中,无需声明数组,因为内存随着数组的增长和收缩而分配和释放。DScript 通过以小块分配内存而不是分配单个大块来容纳整个数组来实现这一点。
在 DScript 中,数组存储为链表。例如,假设你创建一个包含 10 个数字的数组如下:
DScript 分配 10 个小的内存块,每个块保存一个数字。每个内存块包含指向列表中下一项的指针,即数字 1 指向 2,2 指向 3,依此类推。最后,数字 10 不指向任何内容,因为这是列表的末尾。
链表结构让你可以用 DScript 列表做传统数组无法做的事情。例如,以下语句将 Array 中的第三个元素替换为文本字符串:
这在大多数编程语言中是不可能的,因为文本字符串存储所需的内存比数字多。然而,由于 DScript 将数组存储为单独内存块的列表,它只需分配一个内存块来保存文本字符串,释放保存数字 3 的块,并更新指针,使 2 指向字符串,字符串指向 4。结果是一个等同于以下的列表:
链表结构让你可以:
- 在同一数组中存储不同类型的数据
- 动态更改元素的类型
- 动态添加和删除数组中的元素
然而,这种额外功能是有代价的;处理链表可能比传统数组慢。例如,如果你有一个包含 1000 个元素的数组,并且你想读取第 900 个元素的值,为传统语言编写的程序可以计算该元素的确切内存位置并直接访问它。对于链表,程序必须遍历第 900 个元素之前的所有 899 个元素,才能找到存储第 900 个元素的内存位置。
幸运的是,只要你使用列表处理功能,列表提供了额外的功能让你绕过这种低效率。以下代码为列表中的每个元素加一:
只要列表很短,此代码就相当高效。然而,当你开始为列表中靠后的元素加一时,DScript 大部分时间都花在遍历列表中的前面元素上。例如,当 n 等于 900 时,DScript 必须遍历 899 个元素两次,一次在计算 List[n]!=null 时,另一次在计算 List[n]+=1 时。
完成此相同功能的更好方法是使用以下语句:
DScript 识别出 List 不是单个数字,并为 List 中的每个元素加一。此代码不仅比 for 循环高效得多,而且比你能在使用传统数组的编程语言中构造的任何 for 循环都高效得多。
参见关于 For 语句。