【问题标题】:Inconsistent evaluation on the result list of assignment operator in Perl?Perl中赋值运算符的结果列表评估不一致?
【发布时间】:2014-12-05 02:55:29
【问题描述】:

结果列表的评估在标量和列表上下文中看起来不一致。如下代码 sn-p 所示,赋值操作 (=) 的左侧是在列表上下文中评估的,但右侧的列表是在标量上下文中评估的。这是预期的吗?有任何语言原则可以解释这种行为吗?

print (($k, $v) = (3, 4, 5)); # output is 34
print scalar (($k, $v) = (3, 4, 5)); # output is 3

【问题讨论】:

  • 这是一个有趣的怪癖。如果您在标量列表之前插入一个数组,您可以获得预期的行为,例如print scalar(@a = ($k,$v) = ...)
  • @TLP,是的,对@a 的额外赋值按预期工作,因为最后评估的赋值运算符是@a 之后的运算符,并且它的左侧和右侧完全相同。记住这一点有点棘手。
  • 您所说的预期行为是什么?
  • @ysth 输出应该是 2,而不是 3。($k, $v) 应该在标量上下文中返回 2。

标签: perl activeperl


【解决方案1】:

与其做完全不同的事情,不如说是前后矛盾。

perl 中的每个运算符在列表和标量上下文中都有定义的行为,而且它们通常完全不同。在列表赋值的情况下,在列表上下文中,它返回其左操作数,而在标量上下文中,它返回其右操作数中的元素计数。

请注意,这个含义使这样的事情起作用:

while ( my ($k,$v) = each %hash ) {

【讨论】:

  • 我认为重点是 scalar 应该返回 2,因为结果列表有 2 个元素长。
  • @TLP:我的观点是上下文不适用于值,它适用于操作。不是列表赋值执行然后结果是标量上下文的情况;列表分配本身是上下文相关的。
  • @ysth,运算符是上下文相关的,这是有道理的,相同的表达式根据上下文返回不同的值是很常见的,但通常这些值是相关的,数组及其长度。即使是设计使给定的例程可以返回任何不相关的值,我认为这种设计可能是有原因的。就像解决某些问题一样,就像您提到的 while 循环一样。使 while 循环正常工作是创建这种不一致语义的唯一原因吗?
  • 原因是它是有用的行为,在那个和其他情况下
  • 关于while的有趣观察
【解决方案2】:

这只是语义以这种方式定义的问题。

这是来自perldoc perlop

类似地,列表上下文中的列表赋值产生的列表 分配给的左值,标量上下文中的列表分配返回 右边的表达式产生的元素数 任务。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    • 2017-09-28
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 2011-08-21
    相关资源
    最近更新 更多