Поиск…


Массив в виде списка

Массив является одним из основных типов переменных 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 ? Что здесь происходит?

  1. Поскольку foo() оцененный в контексте SCALAR , этот список ( @list1, @list2 ) list1 ( @list1, @list2 ) также оценивается в контексте SCALAR
  2. В контексте SCALAR LIST возвращает свой последний элемент. Здесь @list2
  3. Снова в контексте 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'


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow