ArrayのArrayをコピーする時、「こいつぁ…Shallow copyの匂いがするぜぇ…?」と疑うこと
普通に配列をDeep copyしたいならArray.copyで良いわけです。以下のコードを見る限りちゃんと、xとyが違う配列の実体を持っていそうだぞとわかる。
> let x = [|1..5|];; val x : int [] = [|1; 2; 3; 4; 5|] > let y = Array.copy x;; val y : int [] = [|1; 2; 3; 4; 5|] > y.[1] <- 300;; val it : unit = () > y;; val it : int [] = [|1; 300; 3; 4; 5|] > x;; val it : int [] = [|1; 2; 3; 4; 5|]
ただし、ArrayのArray(配列の配列)の場合、内側のArrayに題してcopyが適用されないので、要素毎のコピーであるDeep copyとはならない。
> let x = [|[|1..3|];[|1..3|]|];; val x : int [] [] = [|[|1; 2; 3|]; [|1; 2; 3|]|] > let y = Array.copy x;; val y : int [] [] = [|[|1; 2; 3|]; [|1; 2; 3|]|] > y.[1].[1] <- 300;; val it : unit = () > y;; val it : int [] [] = [|[|1; 2; 3|]; [|1; 300; 3|]|] > x;; val it : int [] [] = [|[|1; 2; 3|]; [|1; 300; 3|]|]
こうじゃなく、配列の要素全てをちゃんとコピーするにはArray.map+copyで内側のArrayを全コピーするようにする。
> let x = [|[|1..3|];[|1..3|]|];; val x : int [] [] = [|[|1; 2; 3|]; [|1; 2; 3|]|] > let y = Array.map (fun z -> Array.copy z) x;; val y : int [] [] = [|[|1; 2; 3|]; [|1; 2; 3|]|] > y.[1].[1] <- 300 ;; val it : unit = () > y;; val it : int [] [] = [|[|1; 2; 3|]; [|1; 300; 3|]|] > x;; val it : int [] [] = [|[|1; 2; 3|]; [|1; 2; 3|]|]
そもそもフルフルにコピーしなきゃいけないようなコード書いてる時点でアレ感あるけど、まぁ嵌ったのでメモっておく。