У меня есть несколько вопросов к этой программе:
- Что намеревается сделать
foreach my $ref (@_)
? Я думаю, что @_ должен быть связан с переданными параметрами, но не совсем уверен.
Да, вы правы. Когда вы передаете параметры в подпрограмму, они автоматически помещаются в массив @_
. (Называется список в Perl). foreach my $ref (@_)
начинает цикл. Этот цикл будет повторяться для каждого элемента в массиве @_
, и каждый раз значению $ref
будет назначаться следующий элемент в массиве. См. Раздел Perlsoc Perlsyn (синтаксис Perl) о for
циклах и foreach
циклах . Также посмотрите раздел Perloc Perlvar (Perl Variables) в Общие переменные для получения информации о специальных переменных, таких как @_
.
Теперь строка my $classes = shift;
удаляет первый элемент в списке @_
и помещает его в переменную $classes
. Таким образом, цикл foreach
будет повторен три раза. Каждый раз для $ref
сначала устанавливается значение $pVectors
, $nVectors
и, наконец, $uVectors
.
.
Кстати, это не совсем скалярные значения. В Perl вы можете получить то, что называется reference
. Это место в памяти структуры данных, на которую вы ссылаетесь . Например, у меня пять учеников, и у каждого ученика есть серия тестов, которые они прошли. Я хочу сохранить все значения каждого теста в хэш-ключе, идентифицируемом идентификатором студента.
Обычно каждая запись в хэше может содержать только один элемент. Однако что, если этот пункт относится к списку, который содержит оценки ученика?
Вот список учеников № 100:
@grades = (100, 93, 89, 95, 74);
А вот как я устанавливаю запись Student 100 в свой хэш:
$student{100} = \@grades;
Теперь я могу говорить о первом классе года для ученика № 100 как $student{100}[0]
. См. Очень короткий урок Perldoc Mark о ссылках .
- В
my @items = sort { $a <=> $b } keys %items;
«элементы» на левой стороне должны отличаться от «элементов» на правой стороне? Почему они используют одно и то же имя?
В Perl у вас есть три основных типа переменных: Списки (что некоторые люди называют Массивы ), Хэши (что некоторые люди называют Keyed Arrays ) и Scalars . В Perl совершенно законно, чтобы разные типы переменных имели одно и то же имя. Таким образом, вы можете иметь $var
, %var
и @var
в вашей программе, и они будут рассматриваться как полностью отдельные переменные 1 .
Обычно это плохая вещь , и это крайне обескураживает. Ситуация ухудшается, когда вы думаете об отдельных значениях: $var
относится к скаляру, а $var[3]
относится к списку, а $var{3}
относится к хешу. Да, это может быть очень, очень запутанным.
В этом конкретном случае у него есть хеш (массив ключей) с именем %item
, и он преобразует ключи в этом хеш-коде в список, отсортированный по ключам. Этот синтаксис может быть упрощен с:
my @items = sort { $a <=> $b } keys %items;
просто:
my @items = sort keys %items;
См. Perldocs о функции sort и о клавишах .
- Что означает $ items {$ items [$ i]} = $ i + 1; цель сделать? Похоже, он просто устанавливает значение для элементов хеша $ последовательно.
Давайте посмотрим на весь цикл:
foreach my $i (0 .. $#items)
{
print VAL "$items[$i]\n";
$items{$items[$i]} = $i + 1;
}
Подпрограмма будет проходить этот цикл один раз для каждого элемента в списке @items
. Это отсортированный список ключей для старого хэша %items
. $#items
означает самый большой индекс в списке предметов. Например, если @items = ("foo", "bar", and "foobar")
, то $#item
будет 2
, поскольку последний элемент в этом списке - $item[2]
, что равно foobar
.
Таким образом, он достигает индекса каждой записи в @items
. ( ПОМНИТЕ : отличается от %item
!).
Следующая строка немного хитрая:
$items{$items[$i]} = $i + 1;
Помните, что $item{}
относится к старому %items
хешу!Он создает новый %items
хэш.Для этого используется каждый элемент в списке @items
.И в качестве значения указывается индекс этого элемента плюс 1. Предположим, что:
@items = ("foo", "bar", "foobar")
В конце он делает это:
$item{foo} = 1;
$item{bar} = 2;
$item{foobar} = 3;
1 Ну, это не на 100% верно.Perl хранит каждую переменную в виде хэш-структуры.В памяти $var
, @var
и %var
будут храниться в той же хэш-записи в памяти, но в позициях, связанных с каждым типом переменной.В 99,9999% случаев это не имеет значения.Насколько вам известно, это три совершенно разные переменные.
Тем не менее, есть несколько редких случаев, когда программист воспользуется этим преимуществом, когда они напрямую работают с памятью в Perl.