6

我有一个记录类型 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。ff.(i).x 是否正确?我也试过

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

但结果相同...(我使用的是 OCaml 版本 4.00.1)有什么问题?如果有人能给我提示,我会很高兴!

4

3 回答 3

9

这是初学者常犯的一个典型错误,Array.create并且是可变状态。我已经详细解释了那里。总结是,Array.create n foo它不会创建foo(怎么可能?)的副本,它会创建一个 case 数组,它们都指向同一个foo.

于 2012-12-22T09:37:12.117 回答
4

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

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

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

于 2012-12-22T09:38:54.173 回答
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}|]
于 2012-12-22T09:46:24.183 回答