2

我曾假设在 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

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

4

2 回答 2

5

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

因为它有用。

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 是很常见的。
于 2013-10-30T17:43:25.173 回答
3

您有两种类型的分配。

第一个是在标量上下文中,这就是逗号运算符在此上下文中的行为方式(它评估两个参数,但丢弃左边的一个并将值返回到右边)。

第二个是列表上下文(当您将变量括在括号中时,您要求的是列表上下文)。在列表上下文中,逗号运算符只是分隔参数并返回整个列表。

从文档

逗号运算符

二进制“,”是逗号运算符。在标量上下文中,它计算其左参数,丢弃该值,然后计算其右参数并返回该值。这就像 C 的逗号运算符。在列表上下文中,它只是列表参数分隔符,并将其两个参数都插入到列表中。这些参数也从左到右进行评估。

http://perldoc.perl.org/perlop.html#Comma-Operator

于 2013-10-30T17:20:42.100 回答