Как получить первый элемент из функции, которая возвращает массив в 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
- так что если