2

假设 num 是一个数组,

@num = (1 .. 10);

要找到它的长度,我们使用以下表达式,

$num = @num;

然后我$num在下面的作业中使用了相同的方法。

@slicenum = $num[1 .. 6];

我知道对于切片数组,我们使用@num而不是$num. 它运行良好,没有抛出任何错误。但是当我打印 的值时@slicenum,它给了我 2 作为结果。

@slicenum = $num[1 .. 6, 10 .. 20];

对于上述作业,结果我得到了 1。

虽然值$num仍然是 10,但请解释一下上述两个赋值中发生了什么。

4

1 回答 1

10

您已经发现了一些 Perl 魔法在起作用。这个标量上下文中的范围运算符(也就是amon指出触发器运算符)似乎想要将范围与 进行比较,它在与整数一起使用时会这样做:..$.

$ perl -lwe '@a = 1..10; @foo = $a[1..6]; print @foo' 
Use of uninitialized value $. in range (or flip) at -e line 1.
Argument "" isn't numeric in array element at -e line 1.
1

$ perl -lwe '$x=<>; @a = 1..10; @foo = $a[1..6]; print @foo' somefile.txt
Name "main::x" used only once: possible typo at -e line 1.
2

正如darch 所提到的,$a[1 .. 6]将标量上下文强加给下标内的表达式:[ EXPR ]。与使用时相反@a[1 .. 6],其中强加了列表上下文。

所以,这部分:

1 .. 6

在标量上下文中意味着if ($. >= 1 and $. <= 6)

$.未初始化时,它返回undef0在数字上下文中计算为)并发出未初始化的警告。当$.不是未初始化时(即当一个文件已经打开并在程序中的某个地方读取时)它返回真或假,或者在这种情况下1或空字符串。在您的情况下,它似乎返回1,然后导致

$num[1 .. 6]

..评估为

$num[1]

作为回报,它返回元素编号 1,即2.

因此,简而言之:该语句1 .. 6具有不同的含义,具体取决于上下文。在列表上下文中,它返回1,2,3,4,5,6,即一个整数范围。在标量上下文中,1如果$.(行数)变量在 1 或 6 之间,则返回 true (),否则返回 false(空字符串)。

以下是文档中对这种现象的提及:

在列表上下文中,它返回从左值到右值计数(递增)的值列表。

[ ... ]

在标量上下文中,“..”返回一个布尔值。该运算符是双稳态的,就像一个触发器,并模拟 sed、awk 和各种编辑器的行范围(逗号)运算符。

于 2013-04-01T11:57:20.073 回答