Разыменование ссылки на список в элементе hash - PullRequest
2 голосов
/ 27 марта 2012

Может кто-нибудь закончить это для меня и объяснить, что вы сделали?

my %hash;

#$hash{list_ref}=[1,2,3];
#my @array=@{$hash{list_ref}};

$hash{list_ref}=\[1,2,3];
my @array=???

print "Two is $array[1]";

Ответы [ 4 ]

6 голосов
/ 27 марта 2012
@array = @{${$hash{list_ref}}};

(1,2,3) - это список.

[1,2,3] - это ссылка на список массив (технически, в Perl нет такой вещи какссылка на список ).

\[1,2,3] - это ссылка на ссылку на массив.

$hash{list_ref} - это ссылка на ссылку на массив.

${$hash{list_ref}} - это ссылка на массив.

@{${$hash{list_ref}}} - это массив.

Поскольку ссылка считается скалярной, ссылка на ссылку является скалярной ссылкой,и в середине шага используется скалярный оператор разыменования ${...}.

1 голос
/ 28 марта 2012

Другие в значительной степени уже ответили на вопрос, но в более общем плане, если вы когда-либо не понимаете структуру данных, используйте Data :: Dumper .Это распечатает структуру таинственного сгустка данных и поможет вам разобрать его.

use strict;     #Always, always, always
use warnings;   #Always, always, always
use feature qw(say);  #Nicer than 'print'

use Data::Dumper;     #Calling in the big guns!

my $data_something = \[1,2,3];

say Dumper $data_something;
say Dumper ${ $data_something };

Давайте посмотрим, что он печатает ...

$ test.pl

$VAR1 = \[
            1,
            2,
            3
          ];

$VAR1 = [
          1,
          2,
          3
        ];

Из первого дампаПохоже, что $data_something - это простая скалярная ссылка на ссылку на массив.Это побудило меня добавить второй Dumper после того, как я запустил программу в первый раз.Это показало мне, что ${ $data_something } теперь является ссылкой на массив.

Теперь я могу получить доступ к этому массиву следующим образом:

use strict;     #Always, always, always
use warnings;   #Always, always, always
use feature qw(say);  #Nicer than 'print'

use Data::Dumper;     #Calling in the big guns!

my $data_something = \[1,2,3];

# Double dereference
my @array = @{ ${ $data_something } };  #Could be written as @$$data_something

for my $element (@array) {
    say "Element is $element";
}

А теперь ...

$ test.pl
Element is 1
Element is 2
Element is 3

Похоже, вы имели в виду:

my $hash{list_ref} = [1,2,3];

, а не:

$hash{list_ref} = \[1,2,3];

Этот последний получил скалярную ссылку на ссылку на массив, которая на самом деле не делает вас всехэто много хорошего, кроме как добавить путаницу в ситуацию.

Тогда все, что вам нужно было сделать, чтобы сослаться на определенный элемент, это $hash{list_ref}->[0].Это просто ярлык для ${ $hash{list_ref} }[0].Его легче читать и понимать.

use strict;
use warnings;
use feature qw(say);

my %hash;
$hash{list_ref} = [1, 2, 3];

foreach my $element (0..2) {
    say "Element is " . $hash{list_ref}->[$element];
}

И ...

$ test.pl
Element is 1
Element is 2
Element is 3

Итак, в следующий раз вы запутаетесь в том, как выглядит конкретная структура данных (и это происходит случший из нас. Ну ... не лучший из нас , это случается со мной), используйте Data::Dumper.

0 голосов
/ 28 марта 2012
[ EXPR ]

создает анонимный массив, присваивает ему значение, возвращаемое EXPR, и возвращает ссылку на него. Это означает, что он практически такой же, как

do { my @anon = ( EXPR ); \@anon }

Это означает, что

\[ EXPR ]

практически совпадает с

do { my @anon = ( EXPR ); \\@anon }

Это не то, что обычно видят.


поставить иначе,

1,2,3 возвращает список из трех элементов (в контексте списка).

(1,2,3) такой же, как предыдущий. Парены просто влияют на приоритет.

[1,2,3] возвращает ссылку на массив, содержащий три элемента.

\[1,2,3] возвращает ссылку на ссылку на массив, содержащий три элемента.


На практике:

my @data = (1,2,3);
print @data;

& # x20;

my $data = [1,2,3];      $hash{list_ref} = [1,2,3];
print @{ $data };        print @{ $hash{list_ref} };

& # x20;

my $data = \[1,2,3];     $hash{list_ref} = \[1,2,3];
print @{ ${ $data } };   print @{ ${ $hash{list_ref} } };
0 голосов
/ 27 марта 2012
my %hash;

#$hash{list_ref}=[1,2,3];

#Putting the list in square brackets makes it a reference so you don't need '\'
$hash{list_ref}=[1,2,3];

#If you want to use a '\' to make a reference it is done like this:
# $something = \(1,2,3); # A reference to a list
#
#   or (as I did above)... 
#
# $something = [1,2,3]; # Returns a list reference 
#
# They are the same (for all intent and purpose)


print "Two is $hash{list_ref}->[1]\n";


# To make it completely referenced do this:
#
# $hash = {}; 
# $hash->{list_ref} = [1,2,3];
#
# print $hash->{list_ref}[1] . "\n";

Чтобы получить массив (как массив или список), сделайте следующее:

my @array = @{ $hash{list_ref} }  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...