9
my $mind = ( 'a', 'little', 'confused' );

这是因为perldoc perlfaq4将上面的行解释如下(添加了重点):

由于您要分配给标量,因此右侧位于标量上下文中。标量上下文中的逗号运算符(是的,它是一个运算符!)计算其左侧,丢弃结果,并计算其右侧并返回结果。实际上,该 列表相似分配给$scalar它最右边的值。许多人把这搞砸了,因为他们选择了一个类似列表的列表,其最后一个元素也是他们期望的计数:

my $scalar = ( 1, 2, 3 );  # $scalar gets 3, accidentally

我理解这意味着在标量上下文中没有列表这样的东西。

但是,ikegami坚持认为它“导致 [s] 为列表运算符,因此它列表文字”。

那么,它是不是一个列表?

4

6 回答 6

8

列表文字实际上是用代码写出的列表,(1, 2, 3)列表文字也是如此,而caller例如是一个可以根据上下文返回列表或标量的函数。

在一行中:

my $x = ...;

看到...标量上下文,所以如果...是一个列表文字,那么你将在标量上下文中有一个列表文字:

my $x = (1, 2, 3);

但是列表文字不会产生列表,因为它包含的逗号运算符会看到标量上下文,这会导致它返回列表文字的最后一项,并在评估它们后丢弃剩余的值。

就函数而言,函数本身会看到调用它的任何上下文,然后将其传播到该函数中返回的任何行。因此,您可以在标量、列表或 void 上下文中使用函数,并且如果该子项的最后一行恰好是列表文字,则该列表文字将看到任何这些上下文并会正常运行。

所以基本上这是一个术语区别,list literal指的是实际源代码中的逗号分隔值列表*,并list指的是放置在 perl 堆栈上的一系列值。

您可以编写具有返回值的子例程,这些返回值的行为类似于数组或就上下文而言类似于列表文字。

sub returns_like_array  {my @x = 1..5; return @x}

sub returns_like_list   {my @x = 1..5; return @x[0 .. $#x]}

*或导致逗号分隔值列表的东西,如逗号或qw()粗逗号=>或哈希或数组切片。

您还可以在此处查看我的答案:如何从在 Perl 中返回数组的函数中获取第一项?其中更详细地介绍了列表。

于 2011-11-22T20:22:17.837 回答
3

我同意你和perlfaq4。引用perldata,这可能是关于这一点的权威文档:

在不需要列表值的上下文中,看起来是列表文字的值只是最后一个元素的值,就像 C 逗号运算符一样。

(强调我的)。

也就是说,ikegami 有权使用他想要的任何术语。不同的人用不同的术语思考不同的语言结构,只要最终结果相同,我认为他们的术语与文档中的术语不同并不重要。(不过,在公共论坛上坚持使用特殊术语并不是一个好主意!)

于 2011-11-22T20:05:14.387 回答
3

问问 Perl!

>perl -MO=Concise,-exec -e"my $s = ($x, $y, $z);"
1  <0> enter
2  <;> nextstate(main 1 -e:1) v:{
3  <0> pushmark v
4  <#> gvsv[*x] s
5  <#> gvsv[*y] s
6  <#> gvsv[*z] s
7  <@> list sKP                      <--- list in (s)calar context.
8  <0> padsv[$s:1,2] sRM*/LVINTRO
9  <2> sassign vKS/2
a  <@> leave[1 ref] vKP/REFC

所以是的,可以在标量上下文中拥有一个列表。

不能在标量上下文中返回列表。(嗯,可以从 XS 开始,但程序会崩溃,可能会出现“Bizarre copy”错误。)


不可能是其他方式。如果存在不同的列表操作和逗号操作,则无法编译以下内容:

sub f { "a", "b", "c" }

这会导致列表操作还是逗号操作?实际上,没有这样的区别,所以是的,它导致了那个操作。

于 2011-11-22T23:03:57.307 回答
2

这不是一个清单。由于您要分配给标量,因此它是逗号运算符 - 评估左侧,评估右侧,返回右侧,并从左到右解析。$scalar将是'confused':)

于 2011-11-22T20:01:20.190 回答
2

这是一个术语和观点的问题。术语在这里很棘手,因为您可以在源代码中编写一个列表,返回一个值列表,或在列表上下文中评估某些内容......而“列表”这个词在每种情况下都意味着微妙的不同!

从技术上讲,标量上下文中不能存在列表,因为 perl(解释器)不会为以下内容创建值列表:

my $x = ('a', 'b', 'c');

迂腐精确时,这被解释为标量上下文中逗号运算符的行为。同样,qw被定义为返回标量上下文中的最后一个元素,因此这里也没有列表:

my $x = qw(a b c);

在这两种情况下(以及我们可以收集的任何其他运算符示例),我们所说的是解释器不会创建值列表。这是一个实现细节。perl 没有理由不能创建一个值列表并丢弃除最后一个之外的所有值。它只是选择不这样做。

Perl 语言是抽象的。在源代码级别('a', 'b', 'c')是一个列表。您可以在对其施加标量上下文的表达式中使用该列表,因此从这个角度来看,列表可以存在于标量上下文中。

最后,这是 [Pp]erl 如何运作的心智模型之间的选择。“标量上下文中的列表返回其最后一个值”模型稍微不准确,但更容易理解。据我所知,没有任何功能不正确的极端情况。“标量上下文中没有列表之类的东西”模型更准确但更难使用,因为您需要考虑标量上下文中每个运算符的行为。

于 2011-11-22T21:27:12.143 回答
1

如果您相信标量上下文中的列表,请拍手

于 2011-11-23T09:08:19.330 回答