Perl: назначение массива хешу
Этот синтаксис работает:
$b{"x"} = [1,2,3];
pp %b;
# Displays ("x", [1, 2, 3])
Но мне нужно иметь возможность динамически создавать содержимое массива и назначать его позже. Это не работает; помощь, какая очевидная часть мне не хватает?
@a = [1,2,3];
$b{"x"} = @a;
pp %b;
# Shows up as ("x", 1) ... not what I want or expected.
Пробовали и эти варианты.
$b{"x"} = [@a]; # ("x", [[1, 2, 3]]) ...close
$b{"x"} = \@a; # ("x", [[1, 2, 3]])
$b{"x"} = [\@a]; # ("x", [[[1, 2, 3]]])
$b{"x"} = %a; # ("x", 0)
$b{"x"} = $a; # ("x", undef)
$b{"x"} = [$a]; # ("x", [undef])
$b{"x"} = @{@a}; # ("x", 0)
И, в идеале, я хотел бы получить массив обратно позже в виде массива.
Ответы
Ответ 1
Недопустимая часть: @a = [1,2,3]
не создает массив из 3 элементов. Он создает массив с одним элементом, который является arrayref.
Вы имели в виду @a = (1,2,3)
.
Чтобы назначить этот массив элементу хэша, вы должны использовать либо $b{"x"} = [@a]
, либо $b{"x"} = \@a
, в зависимости от того, что вы пытаетесь сделать. [@a]
создает новый массив, содержащий копию текущего содержимого @a
. Если содержимое @a
изменяется после этого, оно не влияет на $b{x}
.
С другой стороны, \@a
дает вам ссылку на @a
. Если вы затем измените содержимое @a
, это будет видно в $b{x}
(и наоборот).
Ответ 2
Вам необходимо прочитать документацию perlref, в которой говорится о ссылках.
Существует разница в том, как хранятся ваши массивы:
# this is an array in an array variable
@a = (1, 2, 3);
Стихи, хранящие массив в массиве:
# this is an array in a scalar variable stored as a reference to the previous array:
$b = \@a;
Функционально работает как указатель. Таким образом, вы можете сохранить эту ссылку в хеше:
$x{'something'} = \@a;
Все это работает отлично. То, что вы не поняли, состоит в том, что [] создает массив , который нельзя хранить в переменной массива. Вы должны хранить его в скаляре. Таким образом, вместо этого:
$c = [1, 2, 3];
$x{'else'} = $c;
будет работать.
И доступ и изменение массива перед выполнением второго назначения можно выполнить, используя:
$c->[3] = '4';
или используя его в форме массива разыменовывая его сначала
push @$c, 5;