在Perl中强制列表上下文

xqkwcwgp  于 2022-11-15  发布在  Perl
关注(0)|答案(3)|浏览(222)

我试图理解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'打印出来,但什么也没有得到。这是怎么回事?

yduiuuwa

yduiuuwa1#

您之所以感到困惑,是因为您认为=是一个运算符,而实际上它可以产生两个不同的运算符:列表赋值运算符或标量赋值运算符。Mini-Tutorial: Scalar vs List Assignment Operator说明了它们之间的区别。

my $b = (33,22,11);
------------------            Scalar assign in void context.
        ----------            List literal in scalar context. Returns last.

my @b = (33,22,11);
------------------            List assign in void context.
        ----------            List literal in list context. Returns all.

my $b = ( () = (33,22,11) );
---------------------------   Scalar assign in void context.
        -------------------   List assign in scalar context. Returns count of RHS
               ----------     List literal in list context. Returns all.

my @b = ( () = (33,22,11) );
---------------------------   List assign in void context.
        -------------------   List assign in list context. Returns LHS.
               ----------     List literal in list context. Returns all.

至于你的标题,强制列表上下文本身是不可能的。如果一个函数在需要标量的时候返回一个列表,它会在堆栈上产生额外的值,这会导致运算符得到错误的参数。
但是,您可以执行以下操作:

( EXPR )[0]

( EXPR )[-1]

EXPR将在列表上下文中被调用,但整个函数将只返回所返回列表中的一个元素。

pw9qyyiw

pw9qyyiw2#

标量上下文中的列表赋值返回右侧的元素数(第2种情况)。第4种情况首先将(33, 22, 11)赋值给(),然后将()(其值未更改)赋值给@b

vojdkbi0

vojdkbi03#

回答标题中隐含的问题:
Perl提供了一个scalar内置函数,在不使用它的情况下强制使用标量上下文;类似的list内建并不存在,我想很大程度上是因为它可能意味着许多不同的事情,例如:

list { code to execute in list context };

可以定义为:

sub list (&) { scalar( () = $_[0]->() ) } # return count of elements
sub list (&) { ( $_[0]->() )[0] } # return first element
sub list (&) { ( $_[0]->() )[-1] } # return last element
sub list (&) { for( $_[0]->() ) {} } # return nothing

回答问题的正文:
当被上下文搞糊涂时,请记住运算符会将上下文强加给操作数,而不是相反。在您的问题案例中,您有一个标量赋值,将列表赋值的结果赋给标量,这将列表赋值置于标量上下文中。要了解发生了什么,只需查看列表赋值在标量上下文中将返回什么。(一般来说,运算符返回最有常识的结果,这意味着没有一个适用于所有运算符的易记规则。)

相关问题