在Perl中强制列表上下文

wwa*_*was 29 perl

我试图理解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";
Run Code Online (Sandbox Code Playgroud)

结果是(最后一行是空白的);

 11  

 3 

 33 22 11

 <>
Run Code Online (Sandbox Code Playgroud)

由于第二个打印返回列表的长度,我假设某个地方生成了一个数组,因为标量上下文中的数组计算它的长度.但第4版似乎相信这一假设.我本来期待看到'33 22 11'印刷但没有得到任何东西.这里发生了什么事?

ike*_*ami 15

您会感到困惑,因为您认为=它是单个运算符,而它可能导致两个不同的运算符:列表赋值运算符或标量赋值运算符.迷你教程:标量与列表分配操作员解释了这些差异.

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

至于你的标题,强制列表上下文是不可能的.如果函数在期望标量时返回列表,则会在堆栈上产生额外的值,从而导致运算符获取错误的参数.

但是,您可以执行以下操作:

( EXPR )[0]
Run Code Online (Sandbox Code Playgroud)

要么

( EXPR )[-1]
Run Code Online (Sandbox Code Playgroud)

EXPR 将在列表上下文中调用,但整体将只返回返回列表的一个元素.


cho*_*oba 6

标量上下文中的列表赋值返回右侧的元素数(案例2).案例4首先分配(33, 22, 11)(),然后分配()(其值没有改变)@b.

  • 标量上下文中的列表*赋值*; 不是标量上下文中的列表(请参阅我的回答) (2认同)