В чем разница между хэшем и хэш-ссылкой в Perl?

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

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

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

4 ответов


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

@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 все скаляры, но значения являются особым видом скаляра: hash ссылки, созданные с помощью {}. Ссылки позволяют моделировать "многомерные" хэши. Например, мы можем добраться до Вильмы через

$personal_info{Flintstone}->{SPOUSE}

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

$personal_info{Flintstone}{SPOUSE}

это много ввода, если вы хотите узнать больше о Фреде, поэтому вы можете захватить ссылку как своего рода курсор:

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

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

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

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

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

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

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

add_barney \%personal_info;

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

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


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

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.


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

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

ссылки: разница между хэшем и хэшем ref в форумах perl - Ubuntu

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

delete $hash{$key};

и для хэш-ссылок

delete $hash_ref->{$key};

на На Perl Хэш-Методические Указания - отличный ресурс для понимания хэшей против хэша с хэш-ссылками

есть еще одна ссылка здесь, что имеет больше информации о perl и ссылки.


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

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

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