2011-01-26 50 views
0
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中的标量和列表上下文

由于

回答

7

你的问题最终是“为什么是在第6行标量上下文@backwards”,其中 引发了一个问题,“我怎样才能确定一个术语的上下文?”。

上下文由下式确定“什么是围绕”(即它的“上下文”)的术语。

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

如果你 没有有用的stackoverflow伙伴来告诉你它的上下文,你可以按照什么步骤来找出@ backwards的上下文?

在这里,我们有

print @backwards."\n" 

所以有两个运营商/功能。我们如何知道哪一个将背景 提供给@ backwards?通过咨询优先。近perlop.pod的顶部,我们有Perl的 优先级表(打印是一个“列表操作符”):

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

哦,太好了,现在我们需要知道相片是否是向左或向右。通过咨询 在perlop中的“条款和列表操作符(左侧)”部分( 优先级列表之后)我们看到,打印是向右这里,因为我们还没有括号括 它的参数。

所以串联是更高的优先级,所以级联提供上下文@backwards。

下一步是检查文档(再次perlop中),用于连接:

Binary "." concatenates two strings. 

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

,我们终于拥有它!

@backwards具有标量上下文因为级联提供标量上下文 其每个操作数。

呜。这很简单,不是吗:-)

8

6行给出3因为.操作者施加在其两个操作数的标量上下文,@backwards在标量上下文产生3(因为在标量上下文任何阵列报告在它的元素的数量)。

尝试:

print "@backwards\n"; 

要加入在数组中的元素,可以使用join

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

保持列表上下文会'印刷@backwards,“\ n”` – 2011-01-26 09:17:19

+0

感谢您的回答的另一个选择。 – Prakhar 2011-01-26 12:07:56

4

语境是棘手的。有时几个像素可以使所有的差异。考虑以下两条线:

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

您是否发现了区别?

这两个陈述看起来非常相似。但是,这两起案件发生的情况完全不同。

在第一个语句中,print传递了一个参数列表。 print的文档说明它在它的参数上施加了列表上下文。因此,对本地时间的调用在列表上下文中进行评估,并且该函数返回一个数字列表。

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

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

+0

谢谢你的解释。 – Prakhar 2011-01-26 12:08:15