Ocaml - 访问记录数组中的组件

时间:2012-12-22 09:11:32

标签: arrays ocaml record

我有一个记录类型tt的数组 - 最初有更多组件;-) - 并且喜欢在for循环中更改其值:

type tt={mutable x: int};;
let f0={x= -1};;
let max=10;;
let ff=Array.create max f0;;
for i=0 to max-1 do ff.(i).x <- i;done;;

尽管如此,ff的所有字段都具有值9而不是0到9之间的值。是(。).x是否正确?我也试过

for i=0 to max-1 do f0.x <- i;ff.(i) <- f0;done;;

但结果相同......(我使用OCaml版本4.00.1) 怎么了?如果有人能给我一个提示,我会很高兴的!

3 个答案:

答案 0 :(得分:8)

这是初学者对Array.create和可变状态所做的经典错误。我已经详细解释了there。摘要是Array.create n foo不会创建foo的副本(怎么可能?),它会创建一个所有指向同一foo的案例数组。

答案 1 :(得分:4)

问题是ff数组的所有单元格都包含相同的元素,即f0。您需要为每个单元格创建一个tt类型的新元素。 这是一种方法:

type tt={mutable x: int};;
let max=10;;
let ff=Array.init max (fun i -> {x= i});;

现在您可以修改单元格而不影响其他单元格。

答案 2 :(得分:3)

问题在于,由于记录是可变的,因此它通过引用存储 而不是按值存储,就像您对非可变数据类型所期望的那样(作为整数)所以当你这样做时

let ff=Array.create 10 f0;;

您实际上存储了10个对同一记录的引用。然后每次迭代

for i=0 to max-1 do ff.(i).x <- i;done;;

只是多次更新相同的引用,所以由于上一次迭代是i = 9,因此数组中包含的唯一真实记录会获得该值。

您需要做的是创建10个不同的记录,例如:

# type tt = {mutable x: int};;
type tt = { mutable x : int; }
# let f = Array.init 10 (fun i -> { x = -1});;
val f : tt array =
  [|{x = -1}; {x = -1}; {x = -1}; {x = -1}; {x = -1}; {x = -1}; {x = -1};
    {x = -1}; {x = -1}; {x = -1}|]
# f.(2).x <- 2;;
- : unit = ()
# f;;
- : tt array =
[|{x = -1}; {x = -1}; {x = 2}; {x = -1}; {x = -1}; {x = -1}; {x = -1};
  {x = -1}; {x = -1}; {x = -1}|]