Подтвердить что ты не робот

Какая разница между хешем и хеш-ссылкой в ​​Perl?

Я хотел бы правильно понимать хэши в Perl. Мне пришлось использовать Perl с перерывами в течение некоторого времени, и в большинстве случаев, когда мне это нужно, это в основном связано с обработкой текста.

И каждый раз мне приходится иметь дело с хэшами, он перепутался. Я нахожу синтаксис очень загадочным для хэшей

Хорошее объяснение хешей и хеш-ссылок, их различия, когда они потребуются и т.д., будут очень оценены.

4b9b3361

Ответ 1

Простой хэш близок к массиву. Их инициализации даже выглядят похожими. Сначала массив:

@last_name = (
  "Ward",   "Cleaver",
  "Fred",   "Flintstone",
  "Archie", "Bunker"
);

Теперь представим одну и ту же информацию с хешем (aka ассоциативный массив):

%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";

Предположим, что мы хотим представлять информацию только с немного более богатой структурой:

  • Кливер (фамилия)
    • Уорд (имя)
    • Июнь (имя супруга)
  • щебенки
    • Фред
    • Вильма
  • Бункер
    • Archie
    • Edith

До того, как появились ссылки, плоские хэши-значения ключа были о лучшем, что мы могли бы сделать, но ссылки позволяют

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, поэтому вы можете получить ссылку как своего рода курсор:

$fred = $personal_info{Flintstone};
print "Fred wife is $fred->{SPOUSE}\n";

Потому что $fred в фрагменте выше - hashref, стрелка необходима. Если вы оставите это, но с умным включением use strict, чтобы помочь вам поймать подобные ошибки, компилятор будет жаловаться:

Global symbol "%fred" requires explicit package name at ...

Ссылки на Perl аналогичны указателям на C и С++, но они никогда не могут быть нулевыми. Указатели на C и С++ требуют разыменования, а также ссылки на Perl.

Параметры функции C и С++ имеют семантику pass-by-value: они просто копии, поэтому модификации не возвращаются к вызывающему. Если вы хотите увидеть изменения, вам нужно передать указатель. Вы можете получить этот эффект со ссылками на Perl:

sub add_barney {
    my($personal_info) = @_;

    $personal_info->{Rubble} = {
        FIRST  => "Barney",
        SPOUSE => "Betty",
    };
}

add_barney \%personal_info;

Без обратной косой черты add_barney получило бы копию, которая была выброшена, как только возвращается sub.

Обратите внимание также на использование "жирной запятой" (=>) выше. Он автоматически выводит строку слева и делает инициализацию хеширования менее синтаксически шумной.

Ответ 2

Ниже показано, как вы можете использовать хэш и хеш-ссылку:

my %hash = (
    toy    => 'aeroplane',
    colour => 'blue',
);
print "I have an ", $hash{toy}, " which is coloured ", $hash{colour}, "\n";

my $hashref = \%hash;
print "I have an ", $hashref->{toy}, " which is coloured ", $hashref->{colour}, "\n";

Также см. perldoc perldsc.

Ответ 3

Хэш - это базовый тип данных в Perl. Он использует ключи для доступа к его содержимому.

Хеш ref является аббревиатурой к ссылка на хэш. Ссылки скаляров, то есть простых значений. это скалярное значение, которое содержит по существу, указатель на фактический сам хэш.

Ссылка: разница между hash и hash ref в perl - Форумы Ubuntu

Разница также заключается в синтаксисе удаления. Как и C, perl работает так, как хэш:

delete $hash{$key};

и для ссылок Hash

delete $hash_ref->{$key};

Perl Hash Howto - отличный ресурс для понимания хэша и хэша с хэш-ссылками

Здесь есть еще одна ссылка которая содержит дополнительную информацию о perl и ссылках.

Ответ 4

Смотрите perldoc perlreftut, который также доступен в вашей собственной командной строке компьютера.

Ссылка - это скалярное значение, которое относится ко всему массиву или всему хэшу (или к чему-либо еще). Имена - это один из видов ссылок, с которыми вы уже знакомы. Подумайте о президенте Соединенных Штатов: грязный, неудобный мешок с кровью и костями. Но говорить о нем или представлять его в компьютерной программе все, что вам нужно, это простая и удобная скалярная строка "Барак Обама".

Ссылки в Perl похожи на имена массивов и хешей. Это Perl частные, внутренние имена, поэтому вы можете быть уверены, что они недвусмысленны. В отличие от "Барака Обамы", ссылка ссылается только на одну вещь, и вы всегда знаете, на что она ссылается. Если у вас есть ссылка на массив, вы можете восстановить весь массив из него. Если у вас есть ссылка на хэш, вы можете восстановить весь хеш. Но эта ссылка по-прежнему является простым и компактным скалярным значением.