标量与Perl中的列表上下文

Eri*_*ric 3 perl scalar list

我在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";
Run Code Online (Sandbox Code Playgroud)

输出是:

list context: doo dabba yabba
scalar1 context: oodabbadabbay
scalar2 context: doo
print context: doodabbayabba
Run Code Online (Sandbox Code Playgroud)

我不理解的是scalar1上下文:

这本书说"反向某事"给出了一个列表上下文,所以我猜qw/ yabba dabba doo /是被视为一个列表和reverse qw/ yabba dabba doo /('doo','dabba','yabba').

因此,$backward = something这意味着某些东西是标量,所以我期待结果'doo dabba yabba',但它是不同的:'oodabbadabbay'.

我想,原因是因为无法直接将列表设置为标量.所以我做了scalar2测试:只打印列表中的最新项目.为什么?为什么不在scalar1测试?

标量测试输出如何工作?

cjm*_*cjm 10

首先,qw/ yabba dabba doo /只是语法糖('yabba', 'dabba', 'doo').他们的意思是一样的.

反向函数接受一个列表.在列表上下文中,它会反转列表.在标量上下文中,它确实join('', @list)然后反转该字符串中的字符并返回它.

记住这一点

$backward = reverse qw/ yabba dabba doo /;
$notbackward = qw/ yabba dabba doo /;
Run Code Online (Sandbox Code Playgroud)

手段

$backward = reverse ('yabba', 'dabba', 'doo');
$notbackward = ('yabba', 'dabba', 'doo');
Run Code Online (Sandbox Code Playgroud)

reverse函数提供列表上下文并$notbackward =为我们提供标量上下文.这意味着逗号运算符位于第一行的列表上下文中,而第二行的标量上下文.在列表上下文中,逗号运算符创建列表.在标量上下文中,它评估两个操作数并返回右手操作数.这意味着('yabba', 'dabba', 'doo')标量上下文中的值是'doo',这就是分配给它的值$notbackward.


mob*_*mob 7

所有Perl函数,包括sub您定义的任何函数,都可以检测它们是否在"标量"或"列表"上下文中被调用,并且有许多函数可以根据此上下文更改其行为.

除了Do Do I Mean之外,很少有关于函数何时以及如何以不同方式处理这两个上下文的约定(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 /;
Run Code Online (Sandbox Code Playgroud)

行为是

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
Run Code Online (Sandbox Code Playgroud)

(*) - 标量列表对标量的赋值不同于数组赋值到标量 - 这是列表数组之间最重要的区别之一:

@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"
Run Code Online (Sandbox Code Playgroud)