我似乎遇到了几种不同的方法来查找数组的大小。这三种方法之间有什么区别?
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
我似乎遇到了几种不同的方法来查找数组的大小。这三种方法之间有什么区别?
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
$[
指定了“数组中第一个元素的索引和子字符串中第一个字符的索引”(perldoc perlvar
)。它默认设置为0,强烈不建议将其设置为非0值。 - Keith Thompson”已经被弃用了(已有十年左右)。现在使用“$[
”会引发弃用警告,即使您没有打开警告功能。在5.16版本中,将任何非零值分配给“$[”都将导致错误。我们能不能不再提到“$[
”了? - ikegamiscalar @arr
和 $#arr
之间差异的人仍然应该了解 $[
的可能影响,即使这种情况很少见。 - Keith Thompson首先,第二个表达式 ($#array
) 和另外两个表达式不等同。 $#array
返回数组的最后一个索引,它比数组大小少一。
另外两个表达式 (scalar @arr
和 $arrSize = @arr
) 实际上是相同的。你只是使用了两种不同的方法来创建标量上下文。这归结为可读性的问题。
我个人更喜欢以下方式:
say 0+@array; # Represent @array as a number
say scalar(@array); # Represent @array as a scalar
并且
my $size = @array;
say $size;
单独看这个代码,后者看起来很清晰,但是当它与其他代码组合时,我发现多余的行会降低其清晰度。它对于教授在标量上下文中使用@array
非常有用,也许如果您想多次使用$size
。
my $size=@array
看起来可能是一种错误,其中使用了错误的符号。 - Nate C-Kscalar
,所以你正在将列表强制转换为标量环境。这是正确使用它的原因。你的示例完全做了同样的事情,但依赖于在隐式标量环境中评估列表变量时 Perl 的行为。因此,你的示例要求读者了解 Perl 在该上下文中的隐式行为。你只是向表达式添加了一层隐式行为,并且 Perl 已经有太多的隐式行为,你必须通过推理才能解码程序。 - Nate C-Kscalar
是因为你正在将列表强制转换为标量上下文”,你证明了我学习错误教训的观点。这是完全错误的。 scalar
永远不会强制转换任何列表。(如果它这样做了,scalar(@array)
和 scalar(@array[0..$#array])
将返回相同的结果。)scalar(@array)
告诉 @array
返回一个标量,而你已经用 my $size=
告诉它要这样做了。 - ikegami通过将数组强制转换为标量上下文来获取其大小,此时它会被计算为其大小:
print scalar @arr;
这是将数组强制转换为标量上下文的另一种方式,因为它被分配给了一个标量变量:
my $arrSize = @arr;
这将获取数组中最后一个元素的索引,因此实际上是大小减1(假设索引从0开始,尽管在Perl中可以调整,但通常不是一个好主意):
print $#arr;
这最后一个方法不太适合用于获取数组大小。如果您只想获取数组的最后一个元素,则此方法会很有用:
my $lastElement = $arr[$#arr];
同时,正如你可以在Stack Overflow上看到的那样,大多数语法高亮显示器无法正确处理这个结构...
$arr[-1]
来获取最后一个元素。使用$arr[-2]
来获取倒数第二个元素,以此类推。 - tuomassalo使用第二种方法,添加1:
print $#arr + 1; # Second way to print array size
for [0..$#array] { print $array[$_ ] }
这段代码非常适合用于遍历数组。它的优点在于,你可以同时得到元素和计数器,并且它们是对齐的。 - Westrock如果我们稍微修改第二个表达式,所有三个表达式都会得到同样的结果:
my @arr = (2, 4, 8, 10);
print "First result:\n";
print scalar @arr;
print "\n\nSecond result:\n";
print $#arr + 1; # Shift numeration with +1 as it shows last index that starts with 0.
print "\n\nThird result:\n";
my $arrSize = @arr;
print $arrSize;
例子:
my @a = (undef, undef);
my $size = @a;
warn "Size: " . $#a; # Size: 1. It's not the size
warn "Size: " . $size; # Size: 2
The special variable
$#array
tells you the index of the last element of an array:print $mixed[$#mixed]; # last element, prints 1.23
You might be tempted to use
$#array + 1
to tell you how many items there are in an array. Don’t bother. As it happens, using@array
where Perl expects to find a scalar value (“in scalar context”) will give you the number of elements in the array:
if (@animals < 5) { ... }
perldata文档也在“标量值”部分中涵盖了这一点。
If you evaluate an array in scalar context, it returns the length of the array. (Note that this is not true of lists, which return the last value, like the C comma operator, nor of built-in functions, which return whatever they feel like returning.) The following is always true:
scalar(@whatever) == $#whatever + 1;
Some programmers choose to use an explicit conversion so as to leave nothing to doubt:
$element_count = scalar(@whatever);
在同一部分之前的文档中介绍了如何获取数组的最后一个元素的索引。
数组的长度是一个标量值。您可以通过计算
csh
中的$#days
来找到数组@days
的长度。但是,这不是数组的长度;它是最后一个元素的下标,因为通常有一个0th元素。
以下内容来自于perldata,应该是安全的引用:
The following is always true:
scalar(@whatever) == $#whatever + 1;
只要你不使用$#whatever++这样的语法并神秘地增加数组大小。
数组索引从0开始。
以及
You can truncate an array down to nothing by assigning the null list () to it. The following are equivalent:
@whatever = (); $#whatever = -1;
这让我想到了我正在寻找的内容,即如何检测数组是否为空。我发现可以使用 $#empty == -1 进行判断。
有多种方法可以打印数组的大小。以下是所有用法的含义:
假设我们的数组为my @arr = (3,4);
这是获取数组大小的正确方法。
print scalar @arr; # Prints size, here 2
$#arr
可以得到数组的最后一个索引号。因此,如果数组大小为10,则其最后一个索引号为9。
print $#arr; # Prints 1, as last index is 1
print $#arr + 1; # Adds 1 to the last index to get the array size
perl -le 'local $[ = 4; my @arr = (3, 4); print $#arr + 1;' # prints 6
my $size = @arr;
print $size; # Prints size, here 2
实际上,方法三和方法一是相同的。
使用int(@array)
,因为它将参数视为标量。
print 0 + @arr
,print "".@arr
,print ~~@arr
。print 0 + @arr
将数组 @arr 强制转换为数字并将其与零相加,然后输出结果。print "".@arr
使用字符串连接操作符将 @arr 数组中的元素连接成一个字符串,并打印结果。print ~~@arr
将数组 @arr 强制转换为布尔值,然后再次强制将其转换为数字。这会将空数组转换为 0,非空数组转换为 1,并输出结果。"".@arr
,因为"@arr"
会产生完全不同的效果。 - ikegami