Простой хеш близок к массиву. Их инициализации даже похожи. Первый массив:
@last_name = (
"Ward", "Cleaver",
"Fred", "Flintstone",
"Archie", "Bunker"
);
Теперь давайте представим ту же информацию с помощью хэша (он же ассоциативный массив):
%last_name = (
"Ward", "Cleaver",
"Fred", "Flintstone",
"Archie", "Bunker"
);
Хотя они имеют одно и то же имя, массив @last_name
и хэш %last_name
полностью независимы.
С помощью массива, если мы хотим узнать фамилию Арчи, мы должны выполнить линейный поиск:
my $lname;
for (my $i = 0; $i < @last_name; $i += 2) {
$lname = $last_name[$i+1] if $last_name[$i] eq "Archie";
}
print "Archie $lname\n";
С хэшем синтаксически он намного более прямой:
print "Archie $last_name{Archie}\n";
Скажем, мы хотим представить информацию с немного более богатой структурой:
- Кливер (фамилия)
- приход (имя)
- июнь (имя супруга)
- щебенки
- Бункер
До появления ссылок плоские хэши значений ключа были лучшими, что мы могли сделать, но ссылки позволяют
my %personal_info = (
"Cleaver", {
"FIRST", "Ward",
"SPOUSE", "June",
},
"Flintstone", {
"FIRST", "Fred",
"SPOUSE", "Wilma",
},
"Bunker", {
"FIRST", "Archie",
"SPOUSE", "Edith",
},
);
Внутренне все ключи и значения %personal_info
являются скалярами, но значения представляют собой особый вид скаляров: ссылки на хеш, созданные с помощью {}
. Ссылки позволяют нам моделировать «многомерные» хеши. Например, мы можем добраться до Вилмы через
$personal_info{Flintstone}->{SPOUSE}
Обратите внимание, что Perl позволяет опускать стрелки между индексами, поэтому приведенное выше эквивалентно
$personal_info{Flintstone}{SPOUSE}
Это много печатать, если вы хотите узнать больше о Фреде, так что вы можете взять ссылку как курсор:
$fred = $personal_info{Flintstone};
print "Fred's wife is $fred->{SPOUSE}\n";
Поскольку $fred
в приведенном выше фрагменте является хеш-кодом, стрелка необходима. Если вы оставите его, но умно включите use strict
, чтобы помочь вам отлавливать подобные ошибки, компилятор будет жаловаться:
Global symbol "%fred" requires explicit package name at ...
Ссылки на Perl похожи на указатели в C и C ++, но они никогда не могут быть нулевыми. Указатели в C и C ++ требуют разыменования, как и ссылки в Perl.
Параметры функций C и C ++ имеют семантику передачи по значению: они просто копии, поэтому модификации не возвращаются к вызывающей стороне. Если вы хотите увидеть изменения, вы должны передать указатель. Вы можете получить этот эффект со ссылками в Perl:
sub add_barney {
my($personal_info) = @_;
$personal_info->{Rubble} = {
FIRST => "Barney",
SPOUSE => "Betty",
};
}
add_barney \%personal_info;
Без обратной косой черты add_barney
получил бы копию, которая выбрасывается, как только саб возвращается.
Обратите внимание также на использование "жирной запятой" (=>
) выше. Он автоматически цитирует строку слева и делает синтаксически менее шумными инициализации хэша.