Как получить первый элемент из функции, которая возвращает массив в Perl?

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

functionReturningArray()[1]

За исключением того, что не работает.

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

3 ответа

Решение
my $item = (function_returning_list())[0];

Функции не могут возвращать массивы, они могут возвращать содержимое массива (то есть списка). Списки индексируются, начиная с 0первый элемент возврата функции (func)[0], Вы также можете сказать

my ($item) = function_returning_list();

Это ставит function_returning_list в контексте списка и присваивает (по порядку) переменным в левом списке.

Важно отметить, что

sub function_returning_list {
    return ("a", "b", "c")
}

my $item = function_returning_list();

скорее всего, не будет делать то, что вы ожидаете. $item переменная будет назначена "c", Это потому, что в скалярном контексте нет такой вещи, как список. Вместо этого у вас есть оператор запятой в скалярном контексте, который оценивает левое выражение в пустом контексте, отбрасывает результат, а затем оценивает правую часть в скалярном контексте.

Я называю последовательность (а не список), и это полезно, если несколько ситуаций, таких как стиль C for петли.

Первый, [1] это второй элемент в списке, так как Perl использует индексы, основанные на 0.

Во-вторых, вам нужно, чтобы возврат функции оценивался в контексте списка, чтобы иметь доступ к списку.

(functionReturningArray())[0]

Идя на шаг дальше, чем обсуждение ниже ответа Чэса, не существует такого понятия, как период списка.

В отличие от Python, который имеет тип кортежа, выполняющий эту роль, списки Perl являются полностью конструкцией стеков в компиляторе / интерпретаторе. Вот почему вы не можете взять ссылку на список.

Подобно тому, как Python использует кортежи, perl автоматически помещает и сдвигает свой стек для перемещения по группам переменных, когда такая конструкция, как = оператор присваивания используется. (Правила приоритета Perl - это то, что требует скобок, так как = крепче, чем ,). Разница на макроуровне между механизмами Perl и Python заключается в том, что контекст распространяется по всему выражению.

Поэтому, когда в скалярном контексте, этот контекст распространяется на каждый из , операторы и оператор выполняет свою левую сторону в пустом контексте и правую сторону в скалярном контексте, который затем возвращает. Однако в контексте списка , Оператор помещает свои аргументы в стек, все из которых выполняются в контексте списка. Стек затем передается через оператор присваивания, а затем сдвигается в lvalue. Сам стек / список является неизменным для кода уровня Perl, его инструменты модификации - фактически весь синтаксис Perl.

Поэтому, хотя неверно ссылаться на список в скалярном контексте (потому что такого не может быть), вы можете ссылаться на поведение списка как синтаксические конструкции (построенные , оператор, построенный из среза массива или среза списка). В скалярном контексте поведение спискообразных конструкций заключается в возвращении последнего элемента списка. Как это достигается, зависит от операторов в выражении. это, конечно, в отличие от поведения массивов в скалярном контексте, которые возвращают их длину.

Чтобы уточнить на примере и, наконец, соблюдать правила и на самом деле ответить на вопрос:

Если предположить, my @array = (10, 11, 12);

  • скалярный контекст

    my $val = (10, 11, 12);        # $val is 12
    my $val = (10 .. 20)[0 .. 5];  # $val is 15      
    my $val = @array;              # $val is 3
    my $val = function();          # $val is the last executed expression
    
    • так что если function заканчивается 10, 11, 12 тогда значение будет 12
    • если это вместо @array тогда значение будет 3
    • и если это заканчивается 10, 11, 12, @array значение также 3

  • контекст списка

    my ($val) = (10, 11, 12);        # $val is 10
    my ($val) = (10 .. 20)[0 .. 5];  # $val is 10
    my ($val) = @array;              # $val is 10
    my ($val) = function();          # $val is the first executed expression
                                     # in the last statement.
    
    • так что если function заканчивается 10, 11, 12 тогда значение будет 10
    • если это вместо @array тогда значение будет 10
    • и если это заканчивается 10, 11, 12, @array значение также 10

  • и для полноты, список списка захватывает весь список в массив

    my @val = (10, 11, 12);        # @val is 10, 11, 12
    my @val = (10 .. 20)[0 .. 5];  # @val is 10, 11, 12, 13, 14, 15
    my @val = @array;              # @val is 10, 11, 12
    my @val = function();          # @val is the the last executed statement
    
    • так что если function заканчивается 10, 11, 12 затем @val будет 10, 11, 12
    • если это вместо @array затем @val будет 10, 11, 12
    • и если это заканчивается 10, 11, 12, @array затем @val будет 10, 11, 12, 10, 11, 12
Другие вопросы по тегам