Кажется, я натолкнулся на несколько разных способов найти размер массива. В чем разница между этими тремя методами?
my @arr = (2);
print scalar @arr; # First way to print array size
print $#arr; # Second way to print array size
my $arrSize = @arr;
print $arrSize; # Third way to print array size
print 0+@arr
,print "".@arr
,print ~~@arr
"".@arr
поскольку"@arr"
делает что-то совсем другое.Ответы:
Первый и третий способы одинаковы: они оценивают массив в скалярном контексте. Я бы посчитал это стандартным способом получения размера массива.
Второй способ фактически возвращает последний индекс массива, который (обычно) не совпадает с размером массива.
источник
$[
указывает «Индекс первого элемента в массиве и первого символа в подстроке» (perldoc perlvar
). По умолчанию он установлен на 0, и установка его на любое значение, отличное от 0, крайне не рекомендуется.$[
обескуражен (и был в течение десятилетия).$[
устарела. Использование$[
выдает предупреждение об устаревании, даже если вы не включаете предупреждения. Присвоение чего-либо, кроме нуля,$[
будет ошибкой в 5.16. Можем ли мы перестать упоминать$[
уже?$[
будет знать о его последствиях.scalar @arr
и$#arr
должны еще понять возможные последствия$[
, редко , хотя они есть.Во-первых, второе не эквивалентно двум другим.
$#array
возвращает последний индекс массива, который на единицу меньше размера массива.Два других практически одинаковы. Вы просто используете два разных средства для создания скалярного контекста. Это сводится к вопросу читабельности.
Я лично предпочитаю следующее:
Я нахожу это яснее, чем
и
Последнее выглядит довольно ясно, как это, но я считаю, что лишняя строка лишает ясности, когда часть другого кода. Это полезно для обучения тому, что
@array
делает в скалярном контексте, и, возможно, если вы хотите использовать$size
более одного раза.источник
my $size=@array
Похоже, это может быть ошибкой, когда использовался неправильный символ.scalar
без причины, получают неправильный урок. Они начинают думать, что операторы возвращают списки, которые можно привести в скаляры. Видел это десятки раз.scalar
потому что вы приводите список в скалярный контекст. Это правильная причина использовать его. Ваш пример делает то же самое, но полагается на то, что делает Perl, когда вы оцениваете переменную списка в неявно скалярном контексте. Таким образом, ваш пример требует, чтобы читатель знал о неявном поведении Perl в этом контексте. Вы просто добавляете еще один слой неявного поведения к выражению, и Perl уже имеет слишком много неявного поведения, которое вы должны объяснить, чтобы расшифровать программу.scalar
потому что приводите список в скалярный контекст", Вы доказали мою точку зрения о том, что выучили неправильный урок. Это совершенно неверно. Никакой список никогда не принуждаетсяscalar
. (Если бы он сделалscalar(@array)
иscalar(@array[0..$#array])
вернул бы то же самое.)scalar(@array)
Велит@array
вернуть скаляр, с которым вы уже сказали, что делатьmy $size=
.Это получает размер путем принудительного помещения массива в скалярный контекст, в котором он оценивается как его размер:
Это еще один способ приведения массива в скалярный контекст, поскольку он присваивается скалярной переменной:
Это получает индекс последнего элемента в массиве, так что это на самом деле размер минус 1 (при условии, что индексы начинаются с 0, что настраивается в Perl, хотя обычно это плохая идея):
Этот последний не очень хорош для получения размера массива. Было бы полезно, если вы просто хотите получить последний элемент массива:
Кроме того, как вы можете видеть здесь о переполнении стека, эта конструкция не обрабатывается корректно большинством подсветчиков синтаксиса ...
источник
$arr[-1]
чтобы получить последний элемент. И$arr[-2]
чтобы получить предпоследний, и так далее.$#arr
это не очень полезная функция, и не случайно, что в других языках ее нет.Чтобы использовать второй способ, добавьте 1:
источник
for [0..$#array] { print $array[$_ ] }
работает очень хорошо, хотя, если целью получения количества элементов является перебор массива. Преимущество в том, что вы получаете элемент, а также счетчик, которые выровнены.Все три дают одинаковый результат, если мы немного изменим второй:
источник
Пример:
источник
Разделе «Perl типы переменных» в документации perlintro содержит
Документация perldata также описывает это в разделе «Скалярные значения» .
Ранее в этом же разделе описано, как получить индекс последнего элемента массива.
источник
Существуют различные способы печати размера массива. Вот значения всех: допустим, наш массив
my @arr = (3,4);
Метод 1: скаляр
Это правильный способ получить размер массивов.
Способ 2: индексный номер
$#arr
дает последний индекс массива. поэтому, если массив имеет размер 10, то его последний индекс будет 9.Мы добавляем 1 здесь, считая массив индексированным 0 . Но если его не на основе нуля, эта логика потерпит неудачу .
Приведенный выше пример печатает 6, потому что мы установили его начальный индекс на 4. Теперь индекс будет 5 и 6, с элементами 3 и 4 соответственно.
Способ 3:
Когда массив используется в скалярном контексте, он возвращает размер массива
На самом деле метод 3 и метод 1 одинаковы.
источник
Из perldoc perldata , которую следует с уверенностью процитировать:
До тех пор, пока вы не $ # независимо от ++ и загадочно увеличиваете размер или ваш массив.
и
Что подводит меня к тому, что я искал, как определить, что массив пуст. Я нашел это, если $ # empty == -1;
источник
А
int(@array)
как насчет того, чтобы он стал аргументом скалярным?источник
Чтобы найти размер массива, используйте
scalar
ключевое слово:Чтобы узнать последний индекс массива
$#
(переменная Perl по умолчанию). Это дает последний индекс массива. Поскольку массив начинается с 0, мы получаем размер массива, добавляя его к$#
:Пример:
Вывод:
источник