这是一个Devel :: REPL会话(我的Perl版本是v5.10.1)。你能解释一下结果吗?
0:main$ my $x = 1,2,4
[
1,
2,
4
]
0:main$ my $y = (1,2,4)
Useless use of a constant in void context at (eval 296) line 8.
4
我刚刚开始学习Perl,但仍然遇到了困扰上下文的麻烦。无论如何,我认为我理解为什么第二次任务会做它的作用。那是因为我们有一个标量上下文,这就是为什么根本没有构造列表的原因,我们只是重复执行逗号运算符,而那个opetator只返回它的右操作数。正确?
但是,第一次作业有什么问题?它不应该等同于第二个吗?在某些时候,我认为括号不提供任何神奇的语义来构建列表 - 它们只是将元素组合在一起,如果元素最终在列表上下文中使用,它们只是转换为列表。显然,那不是真的。
好吧,好吧。那么括号的特殊作用是什么?
答案 0 :(得分:6)
Devel::REPL
正在评估列表上下文中的每个输入行,然后打印结果列表。所以有效的第一行就是:
say join ', ' => do {my $x = 1, 2, 4}
解析为:
say join ', ' => do {(my $x = 1), (2), (4)}
所以REPL打印“1,2,4”,因为它从do
块接收了3个值。
第二行是:
say join ', ' => do {my $x = (1, 2, 4)}
解析为:
say join ', ' => do {(my $x = scalar(1, 2, 4))}
标量上下文中的列表返回其最后一个元素,该元素分配给$x
,然后由do
块返回,随后打印“4”。
答案 1 :(得分:5)
我认为第一个语句的行为是Devel::REPL
的结果,但我现在还没有它可以用来测试这个假设。
Perl中的括号主要调整优先级。他们还可以调整解析器查看某些语句的方式,但这不是这种情况。 =
的优先级高于,
,因此在第一个语句中,如果Devel::REPL
评估列表上下文中的语句,则将其解析为第一个元素是赋值结果的列表1到$x
,第二个和第三个值是2和4.在第二个优先级已经改变,结果上下文已经改变,因此,
在标量上下文中,4分配给$x
。
$ perl -MO=Deparse,-p -e 'my $x = 1,2,4'
((my $x = 1), '???', '???');
-e syntax OK
$ perl -MO=Deparse,-p -e 'my $x = (1,2,4)'
(my $x = ('???', '???', 4));
-e syntax OK
我敢打赌,如果您在scalar(my $x = 1,2,4)
中投放Devel::REPL
,则结果为4,$x
等于1。