对“在列表上下文中评估”的含义有一些明显的困惑,特别是与逗号运算符有关。在链接的
perlop
文档中,它说:在列表上下文中,它只是列表参数分隔符,并将其两个参数插入列表中。但是,代码
@y = 9, 8, 7, 6;
say @y, ', ', scalar @y;
给出输出
9, 1
。这尊重这样一个事实,即当用作标量值 (?) 的二元运算符时,逗号运算符 ,
的优先级低于赋值运算符 =
。但是由于我正在分配给列表@y
,难道不应该在列表上下文中评估分配的右侧,并且根据上面的引述,将逗号简单地视为分隔符吗?
我怀疑我只是不真正理解“在列表上下文中评估”的含义,准确地说...
如果你像你应该的那样打开警告,perl 会给你一些关于正在发生的事情的提示:
#!/usr/bin/env perl
use warnings;
use strict;
use feature qw/say/;
my @y = 9, 8, 7, 6;
say @y, ', ', scalar @y;
运行显示
Useless use of a constant (8) in void context at foo.pl line 6.
Useless use of a constant (7) in void context at foo.pl line 6.
Useless use of a constant (6) in void context at foo.pl line 6.
9, 1
@y = 9, 8, 7, 6
是标量上下文中逗号运算符的示例,并且如您所述,是优先规则。它被解析为以逗号分隔的四个不同的子表达式:首先@y = 9
将单元素列表分配给@y
,然后是表达式 8、7 和 6,所有这些都什么都不做并生成警告,以及整个事情如果有任何要返回的内容,将返回 6。如果要将列表分配给变量,则该列表需要放在括号中:
my @y = (9, 8, 7, 6); # Or qw/9 8 7 6/ etc.
问题与上下文无关。[1]这是一个优先级问题。
赋值比逗号优先,所以
my @y = 9, 8, 7, 6;
意味着
( my @y = 9 ), 8, 7, 6;
但你想要
my @y = ( 9, 8, 7, 6 );
请注意,parens 除了覆盖优先级外什么都不做。
警告会发现这个。始终使用
use strict; use warnings;
或等价物!
my @y
足以导致使用列表分配,因此足以导致在列表上下文中评估RHS。参见标量与列表赋值运算符。...不应该在列表上下文中评估作业的右侧...
只是强调这一点:是的,它应该而且是——在先应用优先规则之后。
看到那个
perl -wE'my @ary = localtime, qw(a b); say for @ary'
它为
Useless use of a constant...
打印两个警告(对于 a
和 b
),然后是当 localtime
在列表上下文中运行时返回的值(而不是时间戳字符串,它在标量上下文中执行的操作)。