f #: инициализировать массив массива - PullRequest
1 голос
/ 31 мая 2011

в следующем коде, массив массив 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|]|]

Ответы [ 2 ]

3 голосов
/ 31 мая 2011
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|]|]

То же самое происходит с вашим кодом.

0 голосов
/ 31 мая 2011

Они не одинаковы.

Массивы являются ссылочными типами и хранятся в куче. Когда вы создаете массив с другим массивом в качестве значения по умолчанию, вы сохраняете ссылки на один и тот же массив снова и снова.

Числа это другая вещь. Они неизменны и хранятся по значению в стеке. Таким образом, вы не можете изменить значение 1 на что-либо кроме 1.

Чтобы создать «неровный» массив, вам нужно вызвать Array.init изнутри инициализатора на первый Array.init вызов, чтобы создать новые массивы для каждого слота.

Также; Вы можете использовать Array.create, если хотите, чтобы в каждом слоте было одинаковое значение. Будьте осторожны с ссылочными типами.

let A = Array.init 3 (fun _ -> Array.create 2 0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...