标量上下文中的列表赋值

时间:2012-02-16 07:24:22

标签: perl list variable-assignment scalar

标量上下文中的列表赋值返回右侧的元素数量:

scalar(my ($hello, $there, $world) = (7,8)); #evaluates to 2

为什么它评估右侧并产生2,而不是新定义的列表被评估并返回3?

对我来说,似乎$hello获得7,$there获得8,$world获得undef,然后该列表将在标量上下文中进行评估,这将导致在3中,因为这是列表中元素的数量($hello $there $world)。对我来说,上下文会影响返回计算表达式的哪一部分似乎很奇怪:

my $greeting = (($hello, $there, $world) = (7,8)); #2

my @greeting = (($hello, $there, $world) = (7,8));
my $greeting_length = @greeting; #3

3 个答案:

答案 0 :(得分:15)

记录在perlop(分配运算符部分的最后一句)中计算右侧的元素:

  

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

它的工作原理是你可以写这样的东西:

while (my ($key, $value) = each %hash) { ... }

如果它计算了赋值左侧的元素数量,那将是一个无限循环。

如果您考虑一下,左侧的元素数量与右侧的元素数量相同,或者它是一个常量(当您分配到标量列表时)。在第一种情况下,你计算哪一方没有区别,而在第二种情况下,计算右侧更有用。

另一方面,在列表上下文中,赋值运算符返回左侧列表,因为它更有用。如果在修改列表元素的上下文中使用它,则需要修改刚分配给的变量。

重新:您的评论在您的示例中,(7,8)是一个双元素列表,这就是赋值运算符返回2的原因。当您将较短列表分配给较长列表时在分配发生之前,右侧不会与undef“填充”。相反,右手列表中没有与其关联的值的任何变量都将重置为其默认值。对于标量变量,即undef。对于数组,这是一个空数组。对于哈希,这是一个空哈希。

答案 1 :(得分:6)

对我来说,上下文影响评估哪一方似乎很奇怪:

没有。评估列表赋值运算符的双方(操作数),以及是否在标量上下文或列表上下文中计算列表赋值不会影响操作数的评估。

在标量上下文或列表上下文中评估列表赋值是否仅影响它返回的值。

我之前创建过Scalar vs List Assignment Operator,它试图弄清楚两个赋值运算符之间的差异以及它们在标量和列表上下文中的行为。

答案 2 :(得分:0)

  

为什么它要评估右侧并生成2,而不是评估新定义的列表并返回3?

因为这就是语言定义所说的应该做的,因为那是拉里·沃尔(Larry Wall)决定应该做的。

  

在我看来,$ hello得到7,$那里得到8,$ world得到   undef,然后在标量上下文中评估该列表

不,perl不能那样工作。您假设标量上下文只是通过计算列表结果中元素的数量将在列表上下文中获得的结果转换为标量,但这根本不对。标量上下文意味着一个操作(在这种情况下为赋值)应该产生标量结果,并且通常存在标量结果比列表上下文结果中的元素数更有用,而且每个运算符之间都有差异...您必须检查文档标量产生的这不是统一的。对于列表分配,标量值是右侧的元素数,因为它比常量的接收者数有用得多。例如,如果匹配产生结果,则if (($a, $b) = $s =~ /$re/)为true,而不是因为有两个接收方而总是为true。

  

对我来说,上下文影响被评估的哪一部分似乎很奇怪   返回表达式

perl中有很多奇怪的东西。这种怪异的感觉来自模型之间的不匹配……在这种情况下,您对正交性的期望以及您对“标量上下文”是列表上的运算符的信念,与perl的务实设计和“标量上下文” 的现实形成了对比。建立一个上下文,该上下文确定要产生什么结果。请注意,您可以编写自己的函数,这些函数根据调用的上下文产生完全不同的结果