标量与列表上下文

时间:2019-01-14 11:49:57

标签: perl

想知道以下两个示例在两种情况下do {}返回列表时给出不同结果的背后原理是什么。

perl -wE 'say my $r = do {  (44); }'
44

perl -wE 'say my $r = do {  my ($x) = map $_, 44; }'
1

2 个答案:

答案 0 :(得分:7)

在两种情况下,对$ r的赋值都强制do上的标量上下文。但是,在第一种情况下,列表上的标量上下文会返回列表的最后一个值'44'。

在第二种情况下,对my ($x)的赋值会强制使用列表上下文。在标量上下文中赋给列表的结果是赋值右侧的元素数量。这样你就可以得到。

map $_, 44返回长度为1的列表,其中包含(44)

my ($x) =将列表上下文中的上述结果分配给列表$x,这是由于($x)周围的括号,使得$ x = 44

由于do的赋值,$r块处于标量上下文中,请注意缺少括号,并且正如我在上面所说的,这返回了列表赋值右侧的长度。在这种情况下为1。

看看这样做会发生什么?

perl -wE 'say my $r = () = (1,3,5,7)'

答案 1 :(得分:5)

首先,do都不返回列表。它们在标量上下文中求值,因此它们必须返回单个标量,而不是任意数量的标量(“列表”)。

在第一种情况下,do返回标量上下文中对44求值的结果。这将返回44

scalar(    44    ) ⇒ 44

在第二种情况下,do返回在标量上下文中评估列表分配的结果。这将返回赋值右侧返回的元素数。

scalar(    () = 44    ) ⇒ 1

我相信引起您困惑的真正原因是您不知道赋值运算符以及它们如何受上下文影响。如果是这样,请参见Scalar vs List Assignment Operator,了解您的真实问题。