我试图理解Perl的上下文,结果被一块石头绊倒了;
给出代码;
#!/usr/bin/perl
my $b = (33,22,11);
print "$b\n";
my $b = () = (33,22,11);
print "$b\n";
my @b = (33,22,11);
print "@b\n";
my @b = () = (33,22,11);
print "@b\n";
结果为(最后一行空白);
11
3
33 22 11
<>
由于第二次打印返回了列表的长度,我假设在某个地方生成了一个数组,因为标量上下文中的数组求值为它的长度。但第四次打印似乎与这个假设不符。我本希望看到'33 22 11'
打印出来,但什么也没有得到。这是怎么回事?
3条答案
按热度按时间yduiuuwa1#
您之所以感到困惑,是因为您认为
=
是一个运算符,而实际上它可以产生两个不同的运算符:列表赋值运算符或标量赋值运算符。Mini-Tutorial: Scalar vs List Assignment Operator说明了它们之间的区别。至于你的标题,强制列表上下文本身是不可能的。如果一个函数在需要标量的时候返回一个列表,它会在堆栈上产生额外的值,这会导致运算符得到错误的参数。
但是,您可以执行以下操作:
或
EXPR
将在列表上下文中被调用,但整个函数将只返回所返回列表中的一个元素。pw9qyyiw2#
标量上下文中的列表赋值返回右侧的元素数(第2种情况)。第4种情况首先将
(33, 22, 11)
赋值给()
,然后将()
(其值未更改)赋值给@b
。vojdkbi03#
回答标题中隐含的问题:
Perl提供了一个
scalar
内置函数,在不使用它的情况下强制使用标量上下文;类似的list
内建并不存在,我想很大程度上是因为它可能意味着许多不同的事情,例如:可以定义为:
回答问题的正文:
当被上下文搞糊涂时,请记住运算符会将上下文强加给操作数,而不是相反。在您的问题案例中,您有一个标量赋值,将列表赋值的结果赋给标量,这将列表赋值置于标量上下文中。要了解发生了什么,只需查看列表赋值在标量上下文中将返回什么。(一般来说,运算符返回最有常识的结果,这意味着没有一个适用于所有运算符的易记规则。)