Perl中的标量和列表上下文

时间:2011-01-26 08:29:02

标签: perl

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?

连接,为什么它会转换为标量上下文

由于

3 个答案:

答案 0 :(得分:8)

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

尝试:

print "@backwards\n";

要加入数组中的元素,请使用join

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

答案 1 :(得分:7)

你的问题最终是“为什么@backwards在第6行的标量语境中”,哪个 提出问题,“我怎样才能确定一个术语的背景?”。

上下文由术语“周围的东西”(即其“上下文”)决定。

如何确定术语的上下文?通过查看操作员/功能 正在使用这个词。

如果您自己为自己找出@backwards的背景,可以采取哪些步骤 没有有用的stackoverflow人来告诉你它的背景?

我们有

print @backwards."\n"

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

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

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

因此,连接是更高的优先级,因此连接为@backwards提供了上下文。

下一步是检查文档(再次使用perlop)进行连接:

Binary "." concatenates two strings.

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

我们终于有了它!

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

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

答案 2 :(得分:4)

上下文很棘手。有时,几个像素可以产生重大影响。请考虑以下两行:

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

您是否发现了差异?

这两个陈述看起来非常相似。但在这两种情况下发生的情况却截然不同。

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

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

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