perl中的负数组索引如何工作?

How does negative array index in perl works?

最近我在perl工作中遇到了负指数。基本上,当我们给Perl中的数组一个负索引时,它从后面开始遍历。例如:

1
2
3
@numbers = (1,2,3,4,5,6);
print"$numbers[-1]
"
;

它将输出打印为6。如果我把索引命名为-2,那么它会打印5等等。根据我的理解,阵列内存如下:enter image description here

我想知道,在Perl中,索引-1是如何变成n的。有人能解释一下这是怎么工作的吗?

旁白:如果我在java中使用负指数,那么它就会抛出java.lang.ArrayIndexOutOfBoundsException


Can anyone please explain how does this works?

获取数组元素av_fetch的perl api调用实现了

1
my $real_index = $index < 0 ? @array+$index : $index;

或者更精确,

1
$index += $#array+1 if $index < 0;

有关索引的详细信息

我们前面说过数组索引是非负整数。虽然在某种程度上这是严格正确的,但是Perl允许您使用负索引方便地从数组的末尾对元素进行索引。-1表示最后一个元素,-2表示下一个元素,依此类推。为了简化一点,-1就像$#array的别名…但只有在索引@array的上下文中!

因此,以下内容是等效的:

1
2
$array[ -1 ]
$array[ $#array ]

但要注意:

1
@array[ 0 .. $#array ]

不能写为:

1
@array[ 0 .. -1 ]

因为在这种情况下-1是……范围运算符,它不知道实际需要什么"最高索引数"。

它之所以有效,是因为它在数组的索引上下文中使用时实际上只是一个别名。


Perl数组不是C数组。它们更像Java的EDCOX1 8。这个数据结构包括一些元数据,比如数组的长度,而不仅仅是起始指针。

现在在Perl中,当数组访问代码看到一个负索引时,它会增加数组的长度:给定一个长度为n+1的数组,那么-1 + (n+1)就是索引n。这是一个方便的语言特性,但是一些语言(特别是"系统编程语言",如C)希望避免隐含的开销。


这是一个文档化的特性。(见perldoc perldata下标部分。)


虽然在某种程度上这是严格正确的,但是Perl允许您使用负索引方便地从数组的末尾对元素进行索引。-1表示最后一个元素,-2表示最后一个元素的下一个元素,依此类推。为了简单化一点,-1充当$#array的别名…但只有在索引@array的上下文中!