在Perl中查找数组的大小

Dav*_*vid 235 perl

我似乎遇到了几种不同的方法来查找数组的大小.这三种方法有什么区别?

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
Run Code Online (Sandbox Code Playgroud)

Chr*_*ung 228

第一种和第三种方式是相同的:它们在标量上下文中评估数组.我认为这是获得数组大小的标准方法.

第二种方式实际上返回数组的最后一个索引,它不(通常)与数组大小相同.

  • (1,2,3)的大小为3,索引(默认情况下)为0,1和2.因此,$#arr在这种情况下为2,而不是3. (29认同)
  • @ikegami:是的,但是有人试图理解`scalar @ arr`和`$#arr`之间的区别应该*仍然*理解`$ [`的可能影响,尽管它们很少见. (7认同)
  • 预定义变量`$ [`指定数组中第一个元素的索引,以及子字符串中第一个字符的索引"(`perldoc perlvar`).它默认设置为0,并且非常不鼓励将其设置为0以外的任何值. (5认同)
  • @Keith Thompson,`$ [`气馁(已经十年了).`$ [`已被弃用.即使没有打开警告,使用`$ [`也会发出弃用警告.将任何零但是零分配给`$ [`将是5.16中的错误.我们可以停止提及`$ [`了吗? (5认同)
  • @Keith Thompson,比5.14还要高.但就像我说的那样,它被劝阻和弃用的时间远远超过这个,而且有人使用`$ [`会知道它的影响. (2认同)

ike*_*ami 40

首先,第二个不等于其他两个.$#array返回数组的最后一个索引,该索引比数组的大小小一个.

其他两个实际上是相同的.您只是使用两种不同的方法来创建标量上下文.它归结为可读性问题.

我个人更喜欢以下内容:

say 0+@array;          # Represent @array as a number
Run Code Online (Sandbox Code Playgroud)

我发现它比清楚的更清楚

say scalar(@array);    # Represent @array as a scalar
Run Code Online (Sandbox Code Playgroud)

my $size = @array;
say $size;
Run Code Online (Sandbox Code Playgroud)

后者看起来非常清楚这样,但我发现额外的线条在其他代码的一部分时会明显失去清晰度.它对于教授@array标量上下文中的内容很有用,也许如果你想$size多次使用它.

  • 我个人更喜欢使用"标量"关键字的版本,因为它非常明确地表示它正在强制使用标量上下文.`my $ size = @ array`看起来可能是一个错误,使用了错误的sigil. (15认同)
  • 这是一个非常糟糕的主意.无缘无故地使用"标量"的人会学到错误的教训.他们开始进入他们的脑袋,运营商返回可以强制进入标量的列表.看了几十次. (5认同)
  • 为什么这"没有理由"?您正在使用`标量',因为您正在将列表强制转换为标量上下文.这是使用它的正确理由.您的示例完全相同,但依赖于Perl在隐式标量上下文中评估列表变量时所执行的操作.因此,您的示例要求读者了解Perl在该上下文中的隐式行为.您只是在表达式中添加了一层隐式行为,而Perl已经有太多的隐式行为,您必须通过这些行为来破译程序. (2认同)
  • @Nate CK,Re"为什么这个"没有理由"?你正在使用"标量",因为你正在强制将列表强加到标量语境中",你已经证明了我学习错误课程的观点.这完全是假的.没有列表被"标量"强制执行.(如果确实如此,`scalar(@array)`和`标量(@array [0 .. $#array])`会返回相同的东西.)`标量(@array)`告诉`@ array`返回一个标量,你已经告诉它用`my $ size =`. (2认同)
  • 信不信由你,开发人员必须调试其他开发人员编写的代码.开发人员必须调试他们三年前编写的代码. (2认同)
  • @Nate CK,我并不太担心程序员调试程序的能力. (2认同)

Nat*_*C-K 27

这通过将数组强制转换为标量上下文来获得大小,在该上下文中将其计算为其大小:

print scalar @arr;
Run Code Online (Sandbox Code Playgroud)

这是将数组强制转换为标量上下文的另一种方法,因为它被分配给标量变量:

my $arrSize = @arr;
Run Code Online (Sandbox Code Playgroud)

这得到了数组中最后一个元素的索引,所以实际上它的大小减去1(假设索引从0开始,可以在Perl中调整,尽管这样做通常是个坏主意):

print $#arr;
Run Code Online (Sandbox Code Playgroud)

最后一个用于获取数组大小并不是很好.如果您只想获取数组的最后一个元素,那将非常有用:

my $lastElement = $arr[$#arr];
Run Code Online (Sandbox Code Playgroud)

此外,正如您在Stack Overflow上看到的那样,大多数语法高亮显示器都无法正确处理此构造...

  • 旁注:只需使用`$ arr [-1]`来获取最后一个元素.并且`$ arr [-2]`得到倒数第二个,依此类推. (2认同)

jho*_*nna 6

要使用第二种方式,请添加1:

print $#arr + 1; # Second way to print array size
Run Code Online (Sandbox Code Playgroud)


小智 5

Example:

my @a = (undef, undef);
my $size = @a;

warn "Size: " . $#a;   # Size: 1. It's not the size
warn "Size: " . $size; # Size: 2
Run Code Online (Sandbox Code Playgroud)


Zon*_*Zon 5

如果我们稍微修改第二个,则所有三个都给出相同的结果:

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;
Run Code Online (Sandbox Code Playgroud)

  • 这有什么不同于[this](http://stackoverflow.com/a/7407036/2235132)回答和[this](http://stackoverflow.com/a/18797985/2235132)中提到的内容? (5认同)