为什么我在perl的标量上下文中得到列表中的最后一个值?

k5ifujac  于 2022-11-15  发布在  Perl
关注(0)|答案(2)|浏览(190)

我本以为在perl中,$x=(2,3,4,5)($x)=(2,3,4,5)会给予相同的结果,但测试结果却让我大吃一惊。我想知道为什么会出现这种情况,为什么wantarray会有不同的表现。下面是我的测试和结果:

>perl -e '$x=(1,2,3,5);print("$x\n")'
5
>perl -e '($x)=(1,2,3,5);print("$x\n")'
1
>perl -e '$x=(wantarray ? (1,2,3,5) : 4);print("$x\n")'
4
>perl -e '($x)=(wantarray ? (1,2,3,5) : 4);print("$x\n")'
4

此行为在所有平台上是否一致/可靠?
wantarray用于子程序调用的上下文...

>perl -e '$x=test();sub test{return(1,2,3,5)};print("$x\n")'
5
>perl -e '($x)=test();sub test{return(1,2,3,5)};print("$x\n")'
1
>perl -e '$x=test();sub test{return(wantarray ? (1,2,3,5) : 4)};print("$x\n")'
4
>perl -e '($x)=test();sub test{return(wantarray ? (1,2,3,5) : 4)};print("$x\n")'
1

所以我猜它是一致的,但是为什么列表返回标量上下文中的最后一个值呢?

disbfnqx

disbfnqx1#

所以我猜它是一致的,但是为什么列表返回标量上下文中的最后一个值呢?
因为它很有用。

my $x = f() || ( warn('!!!'), 'default' );

嗯,至少比其他任何选择都有用,而且它也与它更强大的表亲;一致。

sub f { x(), y(), z() };

与相同

sub f { x(); y(); z() };

每个运算符决定了它在标量和列表上下文中返回什么。[1]
有些运算符甚至只返回一个标量。

say time;             # Returns the number of seconds since epoch
say scalar( time );   # Ditto.

但是那些通常返回多个标量的运算符,以及那些返回可变数量的标量的运算符,在标量上下文中不可能返回这个,所以它们会返回其他的东西,这取决于每个运算符来决定是什么。

say scalar( 4,5,6 );           # Last item evaluated in scalar context.
 say scalar( @a );              # Number of elements in @a.
 say scalar( grep f(), g() );   # Number of matching items.
 say scalar( localtime );       # Formatted timestamp.

列表运算符(例如x,y,z)返回列表的最后一项(z)在标量上下文中求值时返回的值。例如,

my $x = (f(),g(),@a);

是一种奇怪的写作方式

f();
 g();
 my $x = @a;

备注
1.同样的道理也适用于subs,尽管在标量上下文中编写调用无用的subs是很常见的。

1cosmwyk

1cosmwyk2#

您有两种类型的分配。
第一个是在标量上下文中,这就是逗号运算符在此上下文中的行为(它计算两个参数,但丢弃左边的参数并返回右边的值)。
第二个是列表上下文(当你用括号括住一个变量时,你需要的是列表上下文)。在列表上下文中,逗号操作符只是分隔参数并返回整个列表。

来自文档
逗号运算符

二进制“”,是逗号运算符。在标量上下文中,它计算左边的参数,丢弃该值,然后计算右边的参数并返回该值。这就像C的逗号运算符。在列表上下文中,它只是列表参数分隔符,并将其两个参数插入列表中。这些参数也是从左到右计算的。
http://perldoc.perl.org/perlop.html#Comma-Operator

相关问题