欢迎来到理性!
在 Reason/OCaml 中,列表是不可变的。在底层,它们是简单的单链表。每次“修改”它们时都会创建新的。这是一个例子:
let a = [1, 2, 3];
let b = [0, ...a];
这类似于 JavaScript 的数组“spread”,只不过这里你采用的是现有的a
,链接一个新节点0
在前面,并称其为b。a
仍然指向[1, 2, 3]
(因此“不可变”)。b
is now [0, 1, 2, 3]
。这是有效的,因为[1, 2, 3]
部分是共享的。
这样做的好处是,您不必担心传递列表并意外地让一个不起眼的函数修改它。列表的不变性允许您纯粹通过查看您现在所关注的值来推理您的代码(因为它永远不会改变!)。
列表的缺点是在末尾添加内容效率低下:
let c = a @ [4]
该操作基本上是获取一个项目的列表,[4]
,并依次附加每一项[1, 2, 3]
到它。就性能而言是线性的。但从列表实现的简单性来看,历史上认为值得进行权衡。
所以 3. 如果您尝试设置列表项,那么这是错误的流程。
- 在您的情况下填充列表的最佳方法是从旧列表中以非变异方式映射它:
let newList = List.map (fun blabla => ...) raw
- 数组也一样。地图覆盖它。有
Array.of_list
and Array.to_list
如果你被困住了。
有关数组的更多信息:OCaml 数组是可变的,并且其大小是不可更改的。将其视为一块内存。您可以通过分配一个新数组Array.make newSize
,然后通过填充它Array.set
。如果您大量调整数组大小,这就没有意义,因此请选择正确的数据结构。
对于 JS 编译,BuckleScript 将 ocaml 数组编译为 JS 数组。因此它是可变的and可调整大小。您将在下面找到您熟悉的 JS 数组操作Js.Array
作为一般启发式,如果您想更改长度:尝试filter
。如果您想更改长度和包含的项目,请尝试fold_left
。否则,map
.
最近,我们开始实现一些不可变的、可调整大小的、可选可变的数组。敬请关注!