在标量上下文中使用列表时,将返回最后一个元素:
@l = qw/ a b c d /;
print scalar ( 1, @l ); # prints 4
列表的最后一个元素是@l
,它在标量上下文中的长度是4
所以最后一个元素是@l
。
为什么当我切片时我没有得到这个元素?
print (( 1, @l )[1]); # prints 'a'. expect: abcd
PS。也许我应该问:为什么在第一个例子中没有发生扁平化?
答案 0 :(得分:6)
这是因为列表和标量上下文之间的行为不同,以及scalar
是运算符而不是子例程调用的事实。 scalar
只能使用一个操作数,因此如果传递多个参数,则将它们放入标量上下文中。这与普通的子程序调用不同,其中参数始终在列表上下文中。
在标量上下文中,逗号运算符计算并丢弃其左侧操作数,然后计算其右侧操作数。因此scalar(1, @l)
评估并放弃1
,然后评估@l
。如你所说,那是4,因为@l
有四个元素
列表切片不出所料地强加了列表上下文,并且在列表上下文中,逗号分隔列表的元素,并且数组和散列被展平。因此(1, @l)[1]
与(1, qw/ a b c d /)[1]
相同,a
像push
和pop
这样的Perl数组运算符的行为方式类似。如果push @l, 1
的行为方式与普通子例程相同并扩展为push 'a', 'b', 'c', 'd', 1
答案 1 :(得分:4)
在第一个示例中,您使用scalar
强制标量上下文
在标量内容,
被解释为标量二元运算符返回右侧参数。
@l = qw/ a b c d /;
@m = (1, @l); # (1,@l) is interpreted in list context
print scalar(@l); # prints 4
print scalar(@m); # prints 5
print scalar('a',@l); # ('a',@l) is interpreted in scalar context
# prints scalar(@l)
print scalar(@l,'a'); # (@l,'a') is interpreted in scalar context
# prints a
perldoc -f scalar
标量EXPR
强制EXPR在标量上下文中解释并返回EXPR的值。
man perlop
逗号操作员
二进制“,”是逗号运算符。 在标量上下文中,它会评估它 左参数,抛弃该值,然后评估它的权利 参数并返回该值。这就像C的逗号运算符一样 在列表上下文中,它只是列表参数分隔符,并插入 它的参数都列在列表中。还评估了这些参数 从左到右。