我在O'Reilly的书中发现了一个有点奇怪的例子:
@backwards = reverse qw/ yabba dabba doo /;
print "list context: @backwards\n";
$backward = reverse qw/ yabba dabba doo /;
print "scalar1 context: $backward\n";
$notbackward = qw/ yabba dabba doo /;
print "scalar2 context: $notbackward\n";
print "print context: ",reverse qw/ yabba dabba doo /;
print "\n";
输出结果为:
list context: doo dabba yabba
scalar1 context: oodabbadabbay
scalar2 context: doo
print context: doodabbayabba
我不理解的是scalar1
上下文:
这本书说'反向某事'给出了一个列表上下文,所以我猜qw/ yabba dabba doo /
被视为列表而reverse qw/ yabba dabba doo /
被视为('doo','dabba','yabba')。< / p>
所以$backward = something
暗示某事物是标量,所以我期待结果'doo dabba yabba',但它是不同的:'oodabbadabbay'。
我想,原因是因为无法直接将列表设置为标量。所以我做了scalar2
测试:只打印列表中的最新项目。为什么?为什么不在scalar1测试中?
标量测试输出如何工作?
答案 0 :(得分:10)
首先,qw/ yabba dabba doo /
只是('yabba', 'dabba', 'doo')
的语法糖。他们的意思是一样的。
reverse函数采用列表。在列表上下文中,它会反转列表。在标量上下文中,它执行join('', @list)
然后反转该字符串中的字符并返回它。
请记住
$backward = reverse qw/ yabba dabba doo /;
$notbackward = qw/ yabba dabba doo /;
装置
$backward = reverse ('yabba', 'dabba', 'doo');
$notbackward = ('yabba', 'dabba', 'doo');
reverse
函数提供列表上下文,$notbackward =
为我们提供标量上下文。这意味着逗号运算符位于第一行的列表上下文中,而第二行的标量上下文。在列表上下文中,comma operator创建一个列表。在标量上下文中,它评估两个操作数并返回右手操作数。这意味着标量上下文中('yabba', 'dabba', 'doo')
的值为'doo'
,这就是分配给$notbackward
的值。
答案 1 :(得分:7)
所有Perl函数,包括您定义的任何sub
can detect whether they are being called in "scalar" or "list" context,并且有许多函数可以根据此上下文更改其行为。
除了Do Do I Mean之外,很少有关于函数何时以及如何以不同方式处理这两个上下文的约定(这whole thread on perlmonks对这些问题进行了很好的讨论),所以你需要依赖于每个函数的文档,用于猜测函数在特定上下文中的作用。
特别针对您的四个例子,
1. @backwards = reverse qw/ yabba dabba doo /
2. $backward = reverse qw/ yabba dabba doo /
3. $notbackward = qw/ yabba dabba doo /;
4. print ..., reverse qw/ yabba dabba doo /;
行为是
1. reverse function, list context: returns list of the elements in reverse order
2. reverse function, scalar context: concatenate argument list to a string,
return reverse of that string
3. list assignment to scalar: returns last element in list (*)
4. also reverse function, list context same as #1
(*) - 对标量的注释列表赋值与 array 对标量的赋值不同 - 这是列表和数组之间最重要的区别之一:
@a = ("x", "y", "z"); $n = @a; # array assignment, $n is array size, or "3"
$n = ("x", "y", "z"); # list assignment, $n is last element, or "z"
答案 2 :(得分:3)
对于这一行:
$backward = reverse qw/ yabba dabba doo /;
你正在反向请求标量。反向的perldoc说:
在标量上下文中,连接 LIST的元素并返回一个字符串 包含所有字符的值 相反的顺序。
因此它会返回每个反转的字母。
有关 $ notbackward = qw / yabba dabba doo /; qw的perldoc //说:
评估单词列表 从STRING中提取出来,使用 嵌入的空格作为单词 分隔符。它可以理解为 大致相当于:
split(’ ’, q/STRING/);
不同之处在于它会生成一个真实的列表 编译时,在标量上下文中 返回列表中的最后一个元素。
因此请求标量只返回列表中的最后一项。
答案 3 :(得分:0)
为简化其他答案,反向实际上做两件事,列出反转和字符串反转。
这被证明是如此令人困惑,以至于perl6将它们拆分为不同命名的函数。