为什么从列表中切片元素不返回列表?

时间:2017-06-28 11:54:02

标签: list perl

在标量上下文中使用列表时,将返回最后一个元素:

@l =  qw/ a b c d /;
print scalar ( 1, @l ); # prints 4

列表的最后一个元素是@l,它在标量上下文中的长度是4

所以最后一个元素是@l

为什么当我切片时我没有得到这个元素?

print (( 1, @l )[1]); # prints 'a'. expect: abcd

PS。也许我应该问:为什么在第一个例子中没有发生扁平化?

2 个答案:

答案 0 :(得分:6)

这是因为列表和标量上下文之间的行为不同,以及scalar运算符而不是子例程调用的事实。 scalar只能使用一个操作数,因此如果传递多个参数,则将它们放入标量上下文中。这与普通的子程序调用不同,其中参数始终在列表上下文中。

标量上下文中,逗号运算符计算并丢弃其左侧操作数,然后计算其右侧操作数。因此scalar(1, @l)评估并放弃1,然后评估@l。如你所说,那是4,因为@l有四个元素

列表切片不出所料地强加了列表上下文,并且在列表上下文中,逗号分隔列表的元素,并且数组和散列被展平。因此(1, @l)[1](1, qw/ a b c d /)[1]相同,a

pushpop这样的Perl数组运算符的行为方式类似。如果push @l, 1的行为方式与普通子例程相同并扩展为push 'a', 'b', 'c', 'd', 1

,则{{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的逗号运算符一样    在列表上下文中,它只是列表参数分隔符,并插入    它的参数都列在列表中。还评估了这些参数    从左到右。