我一直在尝试弄清楚如何在 OCaml 中调整大小已经初始化的数组。然而,似乎虽然您可以编写一个函数来创建一个全新的数组,并复制旧数组的元素(以及额外的槽),但该函数的输出不能分配给现有数组。一个人会怎样做呢?如果没有的话,是否有一种简单的方法可以使用引用来实现这一点?
这是一个小例子:
let rec function_that_adds_to_array storage args ... = (* let's say the function has a set of if-else constructs that controls what it does, and let's further say that one of the cases leads to: *) let new_array = Array.make (Array.length storage) ("Null", ("Null", -2)) in Array.blit collection 0 new_array 0 index; (* index is controlled by the function's recursion *) Array.set new_array index (obj_name, obj_expr); new_array) (* insert the macro at tail *) ... ;; ### main method ### let storage = Array.make 10 ((x : string), (a, b)) in ... while true do ... storage = function_that_adds_to_array storage args....; ...
function_that_adds_to_array(...) 末尾的打印语句确认返回了一个新数组,其中包含初始数组的旧元素,但是,在 main 方法中,存储保持不变。这是因为 OCaml 元素的不变性吗?我认为数组是可变的。我环顾四周,有人提到编写 hack 来让 OCaml 表现得像 Perl,然而,使用一个人的调整大小 hack 函数被证明是徒劳的。有什么办法可以让存储成为一个新的阵列吗?它需要是一个可更新的元组集合(即 (string, (x, y)) )?
最佳答案
在 OCaml 中,您不能分配给变量,句点。对于数组没有特殊限制。但是,您可以将变量绑定(bind)到引用,该引用可以保存相同类型的不同值。这种结构就是命令式语言中通常所说的“变量”。要在变量 x
中拥有不同大小的数组,您可以编写如下代码:
# let x = ref [| 0 |];;
val x : int array ref = {contents = [|0|]}
# Array.length x;;
Error: This expression has type int array ref
but an expression was expected of type 'a array
# Array.length !x;;
- : int = 1
# x := [| 2; 3 |];;
- : unit = ()
# Array.length !x;;
- : int = 2
!
运算符取消对引用的引用,:=
运算符分配新值。
如果您是 OCaml 新手,我将提供我的标准建议,即您应该在决定重新创建您已经了解的命令式语言的模式之前调查不可变数据的使用。如果您不是 OCaml 新手,我为我的无礼表示歉意!
关于arrays - OCaml:动态数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15745557/