Can't understand the reason of such behavior:
let example count =
let arr = Array.create 2 (Array.zeroCreate count)
for i in [0..count - 1] do
arr.[0].[i] <- 1
arr.[1].[i] <- 2
arr
example 2 |> Array.iter(printfn "%A")
Print:
[|2; 2|]
[|2; 2|]
https://dotnetfiddle.net/borMmO
If I replace:
let arr = Array.create 2 (Array.zeroCreate count)
to:
let arr = Array.init 2 (fun _ -> Array.zeroCreate count)
Everything will work as expected:
let example count =
let arr = Array.init 2 (fun _ -> Array.zeroCreate count)
for i in [0..count - 1] do
arr.[0].[i] <- 1
arr.[1].[i] <- 2
arr
example 2 |> Array.iter(printfn "%A")
Print:
[|1; 1|]
[|2; 2|]
https://dotnetfiddle.net/uXmlbn
I think the reason is the fact that the array - a reference type. But I want to understand why this is happening. Since I didn't expect such results.
When you write:
let arr = Array.create 2 (Array.zeroCreate count)
You are creating an array where each element is a reference to the same array. This means that mutating a value using arr.[0]
also mutates the value in arr.[1]
- because the two array elements are pointing to the same mutable array. You end up with:
[| x ; x |]
\ /
[| 0; 0 |]
When you write:
let arr = Array.init 2 (fun _ -> Array.zeroCreate count)
The provided function is called for each position in the arr
array and so you'll end up with different array for each element (and so arr.[0] <> arr.[1]
). You end up with:
[| x ; y |]
/ \
[| 0; 0 |] [| 0; 0 |]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With