在以下代码中,是否为数组A = B
的数组?
let A = Array.init 3 (fun _ -> Array.init 2 (fun _ -> 0))
let defaultCreate n defaultValue = Array.init n (fun _ -> defaultValue)
let B = defaultCreate 3 (defaultCreate 2 0)
如果我将值分配给A and B
,它们会有所不同,发生了什么?感谢。
for i = 0 to 2 do
for j = 0 to 1 do
A.[i].[j] <-i + j
B.[i].[j] <-i + j
printfn "%A vs %A" A B
A = [|[|0; 1|]; [|1; 2|]; [|2; 3|]|] and B = [|[|2; 3|]; [|2; 3|]; [|2; 3|]|]
答案 0 :(得分:3)
let B = defaultCreate 3 (defaultCreate 2 0)
您创建一个数组,然后将此数组用作每个单元格的值。 就像你做了这样的事情:
let a = [|1; 2; 3; 4|]
let b = [|a; a; a; a|]
同一个数组a
用于每个单元格(想想指向a
的指针,你已经习惯了C)。因此,修改b.[0].[1]
将改变每a.[1]
。
在我的样本中:
> b.[0].[1] <- 10;;
val it : unit = ()
> b;;
[|[|1; 10; 3; 4|]; [|1; 10; 3; 4|]; [|1; 10; 3; 4|]; [|1; 10; 3; 4|]|]
您的代码也会发生同样的事情。
答案 1 :(得分:0)
它们不一样。
数组是引用类型,存储在堆上。当您使用另一个数组作为默认值创建数组时,您将一遍又一遍地存储对同一数组的引用。
数字是另一回事。它们是不可变的,并且按值存储在堆栈中。因此,您无法将1
的值更改为1
以外的任何内容。
要创建“锯齿状”数组,您需要从初始化程序内部调用Array.init
到第一个Array.init
调用,为每个插槽创建新数组。
也;如果您希望在每个插槽中具有相同的值,则可以使用Array.create
。但要注意参考类型。
let A = Array.init 3 (fun _ -> Array.create 2 0)