Perl Language
Списки
Поиск…
Массив в виде списка
Массив является одним из основных типов переменных Perl. Он содержит список, который представляет собой упорядоченную последовательность из нуля или более скаляров. Массив - это перенос переменной (и предоставление доступа) к данным списка, как это описано в perldata .
Вы можете назначить список массиву:
my @foo = ( 4, 5, 6 );
Вы можете использовать массив везде, где ожидается список:
join '-', ( 4, 5, 6 );
join '-', @foo;
Некоторые операторы работают только с массивами, поскольку они мутируют список, содержащий массив:
shift @array;
unshift @array, ( 1, 2, 3 );
pop @array;
push @array, ( 7, 8, 9 );
Присвоение списка хешу
Списки также могут быть присвоены хэш-переменным. При создании списка, который будет назначен хеш-переменной, рекомендуется использовать жирную запятую =>
между клавишами и значениями, чтобы показать их взаимосвязь:
my %hash = ( foo => 42, bar => 43, baz => 44 );
The =>
- действительно только специальная запятая, которая автоматически цитирует операнд слева. Итак, вы можете использовать обычные запятые, но отношения не так ясны:
my %hash = ( 'foo', 42, 'bar', 43, 'baz', 44 );
Вы также можете использовать цитированные строки для левого операнда жирной запятой =>
, что особенно полезно для ключей, содержащих пробелы.
my %hash = ( 'foo bar' => 42, 'baz qux' => 43 );
Подробнее см. Comma-оператор perldoc perlop
.
Списки могут быть переданы в подпрограммы
Чтобы передать список в подпрограмму, вы указываете имя подпрограммы и затем указываете ей список:
test_subroutine( 'item1', 'item2' );
test_subroutine 'item1', 'item2'; # same
Внутренне Perl делает псевдонимы для этих аргументов и помещает их в массив @_
который доступен в подпрограмме:
@_ = ( 'item1', 'item2' ); # Done internally by perl
Вы получаете такие аргументы подпрограммы:
sub test_subroutine {
print $_[0]; # item1
print $_[1]; # item2
}
Алиасирование дает вам возможность изменить исходное значение аргумента, переданного подпрограмме:
sub test_subroutine {
$_[0] += 2;
}
my $x = 7;
test_subroutine( $x );
print $x; # 9
Чтобы предотвратить непреднамеренные изменения исходных значений, переданных в вашу подпрограмму, вы должны скопировать их:
sub test_subroutine {
my( $copy_arg1, $copy_arg2 ) = @_;
$copy_arg1 += 2;
}
my $x = 7;
test_subroutine $x; # in this case $copy_arg2 will have `undef` value
print $x; # 7
Чтобы проверить, сколько аргументов было передано в подпрограмму, проверьте размер @_
sub test_subroutine {
print scalar @_, ' argument(s) passed into subroutine';
}
Если вы передадите аргументы массива в подпрограмму, все они будут сплющены :
my @x = ( 1, 2, 3 );
my @y = qw/ a b c /; # ( 'a', 'b', 'c' )
test_some_subroutine @x, 'hi', @y; # 7 argument(s) passed into subroutine
# @_ = ( 1, 2, 3, 'hi', 'a', 'b', 'c' ) # Done internally for this call
Если ваш test_some_subroutine
содержит оператор $_[4] = 'd'
, для вышеупомянутого вызова это приведет к тому, что $y[0]
получит значение d
:
print "@y"; # d b c
Возвратный список из подпрограммы
Разумеется, вы можете возвращать списки из субсайтов:
sub foo {
my @list1 = ( 1, 2, 3 );
my @list2 = ( 4, 5 );
return ( @list1, @list2 );
}
my @list = foo();
print @list; # 12345
Но это не рекомендуется, если вы не знаете, что делаете.
Хотя это нормально, когда результат находится в контексте LIST , в контексте SCALAR все неясно. Давайте посмотрим на следующую строку:
print scalar foo(); # 2
Почему 2
? Что здесь происходит?
- Поскольку
foo()
оцененный в контексте SCALAR , этот список( @list1, @list2 )
list1( @list1, @list2 )
также оценивается в контексте SCALAR - В контексте SCALAR LIST возвращает свой последний элемент. Здесь
@list2
- Снова в контексте SCALAR массив
@list2
возвращает количество его элементов. Здесь2
.
В большинстве случаев правильная стратегия будет возвращать ссылки на структуры данных .
Поэтому в нашем случае мы должны сделать следующее:
return ( \@list1, \@list2 );
Затем вызывающий абонент делает что-то вроде этого, чтобы получить два возвращенных параметра arrayrefs :
my ($list1, $list2) = foo(...);
Использование arrayref для передачи массива в sub
Массивref для @foo
- \@foo
. Это удобно, если вам нужно передать массив и другие вещи подпрограмме. Передача @foo
подобна передаче нескольких скаляров. Но передача \@foo
является единственным скаляром. Внутри подпрограммы:
xyz(\@foo, 123);
...
sub xyz {
my ($arr, $etc) = @_;
print $arr->[0]; # using the first item in $arr. It is like $foo[0]
Хеш как список
В контексте списка хеш сглажен.
my @bar = ( %hash, %hash );
Массив @bar
инициализируется списком двух %hash
хешей
- оба
%hash
сегмента сглажены - новый список создается из сплющенных элементов
-
@bar
array инициализируется этим списком
Гарантируется, что пары ключ-значение объединяются. Ключи всегда индексируются, значения - нечетные. Не гарантируется, что пары ключ-значение всегда сплющены в одном порядке:
my %hash = ( a => 1, b => 2 );
print %hash; # Maybe 'a1b2' or 'b2a1'