Perl中的标量和列表上下文

Pra*_*har 0 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
Run Code Online (Sandbox Code Playgroud)

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

谢谢

Jon*_*ler 8

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

尝试:

print "@backwards\n";
Run Code Online (Sandbox Code Playgroud)

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

print join(', ', @backwards) . "\n";
Run Code Online (Sandbox Code Playgroud)

  • 保持列表上下文的另一个选择是`print @backwards,"\n"` (5认同)

tad*_*dmc 7

你的问题最终是"为什么@backwards在第6行的标量语境中",这引出了一个问题,"如何确定一个术语的上下文?".

上下文由术语"周围的东西"(即其"上下文")决定.

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

如果您没有有用的stackoverflow人员告诉您它的上下文,您可以通过哪些步骤来自己找出@backwards的上下文?

我们在这里

print @backwards."\n"
Run Code Online (Sandbox Code Playgroud)

所以有两个操作员/功能.我们如何知道哪一个为@backwards提供了上下文?通过咨询优先权.在perlop.pod的顶部附近,我们有Perl的优先级图表(print是"list operator"):

left    terms and list operators (leftward)
...
left    + - .
...
nonassoc    list operators (rightward)
Run Code Online (Sandbox Code Playgroud)

哦,太好了,现在我们需要知道打印是向左还是向右.通过查阅perlop中的"术语和列表操作符(向左)"部分(在优先列表之后),我们看到打印在这里是向右的,因为我们没有将其参数括在括号中.

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

下一步是检查docs(perlop)以进行连接:

Binary "." concatenates two strings.
Run Code Online (Sandbox Code Playgroud)

字符串是标量,所以二进制"." 连接两个标量.

我们终于有了它!

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

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