【问题标题】:Scalar vs list context标量与列表上下文
【发布时间】:2019-01-28 09:49:14
【问题描述】:

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

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

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

【问题讨论】:

  • 在第二个示例中,您有一个明确的标量上下文 (my ($x) = ...)。
  • 不完全是,你可以检查$x是44,$r是1。如果是标量上下文,$x也会是1。
  • 好吧perl -MO=Concise ... 显示了差异,但我无法解释上下文列表/标量的真正设置位置。

标签: perl


【解决方案1】:

在这两种情况下,对 $r 的赋值都会强制执行标量上下文。然而,在第一种情况下,列表上的标量上下文返回列表的最后一个值“44”。

在第二种情况下,my ($x) 的赋值强制使用列表上下文,在标量上下文中分配给列表的结果是赋值右侧的元素数。所以你明白了。

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

my ($x) = 在列表上下文中将上面的结果分配给列表$x,因为括号($x) 使得$x = 44

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

看看如果你这样做会发生什么:

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

【讨论】:

  • 并非所有标量上下文都是平等的。 :-) my $r = () = (1,3,5,7)my $r = (1,3,5,7)
  • () = (1,3,5,7) 是对空列表的列表分配。 $r = ... 是来自 ( () = (1.3.5.7) ) 的标量赋值,它给出了分配给空列表的元素数。
  • @Сухой27,关于“并非所有标量上下文都是平等的”。不完全的。并非所有的赋值运算符都是平等的。有一个标量赋值运算符(将其 LHS 作为标量上下文中的左值返回),还有一个 列表赋值运算符(返回其 RHS 返回的标量数在标量上下文中)。有关详细信息,请参阅我的答案中的链接。
  • Re "返回长度为 1 的列表",这只是“返回单个标量”的一种奇怪说法。
【解决方案2】:

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

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

scalar(    44    ) ⇒ 44

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

scalar(    () = 44    ) ⇒ 1

我认为您困惑的真正原因是您不了解赋值运算符以及它们如何受上下文影响。如果是这样,请参阅Scalar vs List Assignment Operator 了解您真正问题的答案。

【讨论】:

    猜你喜欢
    • 2011-07-07
    • 2012-03-07
    • 1970-01-01
    • 2014-01-03
    • 1970-01-01
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    相关资源
    最近更新 更多