【问题标题】:Scalar and List context in PerlPerl 中的标量和列表上下文
【发布时间】:2011-01-26 08:29:02
【问题描述】:
1 @backwards = reverse qw(yabba dabba doo);
2 $backwards = reverse qw(yabba dabba doo);
3 
4 print @backwards; #gives doodabbayabba
5 print $backwards."\n"; #gives oodabbadabbay
6 print @backwards."\n"; #gives 3

在上面的代码中,为什么line 6 会给出 3 作为输出?如果它与 \n 连接,为什么它会转换为标量上下文?

谢谢

【问题讨论】:

    标签: perl


    【解决方案1】:

    第 6 行给出 3,因为 . 运算符对其两个操作数都施加了标量上下文,而标量上下文中的 @backwards 产生 3(因为标量上下文中的任何数组都会报告其中的元素数量)。

    试试:

    print "@backwards\n";
    

    要连接数组中的元素,请使用join

    print join(', ', @backwards) . "\n";
    

    【讨论】:

    • 保持列表上下文的另一个选项是print @backwards, "\n"
    【解决方案2】:

    您的问题最终是“为什么@backwards 在第 6 行的标量上下文中”,它 提出了一个问题,“我如何确定一个术语的上下文?”。

    上下文是由“what is around”(即它的“上下文”)这个词决定的。

    如何确定术语的上下文?通过查看运算符/函数 正在使用该术语。

    如果您自己找出 @backwards 的上下文,您可以遵循哪些步骤 周围没有帮助的 stackoverflow 人员告诉你它的上下文?

    我们来了

    print @backwards."\n"
    

    所以有两个运算符/函数。我们如何知道哪一个提供了上下文 到@backwards?通过咨询优先。在 perlop.pod 的顶部附近,我们有 Perl 的 优先级图表(打印是“列表运算符”):

    left    terms and list operators (leftward)
    ...
    left    + - .
    ...
    nonassoc    list operators (rightward)
    

    太好了,现在我们需要知道打印是向左还是向右。通过咨询 perlop 中的“术语和列表运算符(向左)”部分(紧跟在 优先级列表)我们看到 print 在这里是向右的,因为我们没有封闭 括号中的参数。

    因此串联具有更高的优先级,因此串联为@backwards 提供上下文。

    下一步是检查文档(再次 perlop)的连接:

    Binary "." concatenates two strings.
    

    字符串是标量,所以是二进制的“.”连接两个标量。

    我们终于有了!

    @backwards 具有标量上下文,因为连接提供了标量上下文 它的每个操作数。

    哇。这很容易,不是吗:-)

    【讨论】:

      【解决方案3】:

      上下文很棘手。有时几个像素可以使一切变得不同。考虑以下两行:

      print localtime, "\n";
      print localtime. "\n";
      

      你发现区别了吗?

      这两个语句看起来非常相似。但这两种情况下发生的事情却大不相同。

      在第一条语句中,print 被传递一个参数列表。并且 print 的文档说它在其参数上强加了列表上下文。因此,对 localtime 的调用在列表上下文中进行评估,并且该函数返回一个数字列表。

      在第二个语句中,print 接收一个参数。该参数是通过将调用 localtime 的结果与换行符连接起来创建的字符串。连接运算符在其两个操作数上施加标量上下文。因此,对 localtime 的调用以人类可读的字符串格式返回当前时间。然后将该字符串与换行符连接起来,并将生成的字符串传递给打印。 print 调用仍然在列表上下文中评估其参数,但该上下文对解释单个字符串参数的方式没有影响。

      对于另一个类似的问题,请查看 Perl 中更奇怪的上下文角落,请参阅我几天前在我的博客上发布的 the question。我会在几天后发布解决方案。

      【讨论】:

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