Как получить первый элемент из функции, которая возвращает массив в Perl? - PullRequest
5 голосов
/ 16 сентября 2010

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

functionReturningArray()[1]

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

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

Ответы [ 3 ]

12 голосов
/ 16 сентября 2010
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-style for.

2 голосов
/ 17 сентября 2010

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

В отличие от 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
2 голосов
/ 16 сентября 2010

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

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

(functionReturningArray())[0]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...