【问题标题】:perl 101 subroutine and return valueperl 101 子程序和返回值
【发布时间】:2013-08-14 04:07:12
【问题描述】:

我不明白这将如何返回 4 作为答案。 不确定子程序内部发生了什么。



sub bar {@a = qw (10 7 6 8);}
my $a = bar(); 
print $a; 

# outputs 4

【问题讨论】:

  • 我推荐阅读Learn Perl in about 2 hours 30 minutes中的“上下文”部分。
  • 上下文!我记得在学习 Perl 中,关于这个上下文问题,有一句话说“这是你将在本书中学到的最重要的一课,事实上,这是你在整个 Perl 职业生涯中将学到的最重要的一课”。经过 4 个月的痛苦 Perl OTJ,我可以保证这个人是明智的。

标签: perl


【解决方案1】:

子例程在标量上下文中调用。子例程中的最后一条语句是对@a 的赋值,它是一个表达式,因此成为隐含的​​返回值。在标量上下文中,这计算为赋值右侧返回的元素数(恰好与 @a 中的元素数相同)。

【讨论】:

  • 但是没有return语句。
  • return 隐含在 perl 中
  • @airnet - 我稍微修改了我的答案。
  • @ikegami - 我在哪里说过最后评估的表达式是@a?我说过最后一个语句是对@a的赋值,而这个(语句)是一个表达式。表达式的值(如您所说,是 RHS 值)成为子例程的返回值。关键是发生这种情况因为语句是一个表达式。 “数组长度”是指作为赋值表达式的值的数组长度(不是LHS的长度)。
  • 数组在标量上下文中计算其长度,并且它可以在标量中计算的唯一方法是它是否是返回值。如果您希望我更准确地说明您的帖子有什么问题:1)列表赋值运算符不在标量上下文中评估其 LHS,2)不在标量上下文中评估数组。 3) 数组不计算其长度,4) 列表赋值运算符不计算数组长度。所以是的,你的回答是非常非常错误的。 (我刚刚修好了。)
【解决方案2】:

子例程的每个返回表达式(即return 语句的操作数和子例程的任何最终表达式)都在与子例程调用本身相同的上下文中进行评估。

sub f {
    ...
    return THIS if ...;
    return THIS if ...;
    ...
    if (...) {
        ...
        THIS
    } else {
        ...
        THIS
    }
}

在这种情况下,返回表达式是一个列表赋值。 (@aqw 是赋值的操作数,因此在赋值之前进行求值。)标量上下文中的列表赋值求值为其右侧求值的元素数。

Scalar vs List Assignment Operator

【讨论】:

    【解决方案3】:

    在 Perl 中,如果没有指定 return 语句,子例程的返回值是最后计算的表达式。

    来自perlsub 文档:

    如果没有找到返回并且最后一个语句是一个表达式,它的 返回值。如果最后一条语句是循环控制结构 像 foreach 或 while ,返回值是未指定的。这 empty sub 返回空列表。

    【讨论】:

    • @ikegami - 你似乎误读了(我认为不是故意的)这个答案和我的。尽管您对我们的答案有抱怨,但我们都没有说“最后评估的表达式是@a”。我似乎很清楚,我们都在说最后一个表达式是@a的赋值,这也正是你所说的。你说考虑sub bar { () = qw (10 7 6 8) }。我们应该从考虑它得出什么结论?它的行为就像我们已经描述的那样?太棒了。
    • @Ted Hopp,您声称标量上下文中的列表分配返回了标量上下文中 LHS 的结果。这个例子表明你错了。您的其余观点在您的节点下得到解决,您也在那里提出了它们。如果你想了解真正发生的事情,你应该阅读我的帖子。 [请注意,squiguy 删除了不正确的部分(留下部分答案)。因此,我删除了我之前的评论。]
    • @ikegami - 我确实声称标量上下文中的列表分配返回标量上下文中的LHS结果。你的例子确实表明我这样做是错误的。恭喜,你击落了你的straw man
    • @Ted Hopp,数组是赋值的 LHS 操作数,数组只计算其在标量上下文中的元素数,所以这正是你所说的赋值“计算数组长度。”也许你意思是不同的?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    相关资源
    最近更新 更多