标量上下文中是否存在列表之类的东西?
my $mind = ( 'a', 'little', 'confused' );
这是因为 perldoc perlfaq4
对上面一行的解释如下(强调是已添加):
由于您要分配给标量,因此右侧是标量 语境。标量上下文中的逗号运算符(是的,它是一个运算符!) 评估其左侧,丢弃结果,然后评估 它位于右侧并返回结果。实际上,那 list-lookalike 将其最右边的值分配给
$scalar
。很多人 搞砸了,因为他们选择了一个类似列表,其最后一个元素 也是他们期望的计数:我的 $scalar = ( 1, 2, 3 ); # $scalar 意外地得到了 3
我理解这意味着标量上下文中不存在列表之类的东西。
然而,ikegami 坚持认为它“列表中的结果运算符,所以它是一个列表文字。”
那么,它是不是一个列表?
my $mind = ( 'a', 'little', 'confused' );
And it's because perldoc perlfaq4
explains the line above as follows (emphasis added):
Since you're assigning to a scalar, the righthand side is in scalar
context. The comma operator (yes, it's an operator!) in scalar context
evaluates its lefthand side, throws away the result, and evaluates
it's righthand side and returns the result. In effect, that
list-lookalike assigns to$scalar
it's rightmost value. Many people
mess this up because they choose a list-lookalike whose last element
is also the count they expect:my $scalar = ( 1, 2, 3 ); # $scalar gets 3, accidentally
What I understand this to mean is that there is no such thing as a list in scalar context.
However, ikegami maintains that it "result[s] in a list operator, so it is a list literal."
So, is it a list or not?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
列表文字实际上是用代码编写的列表,因此
(1, 2, 3)
是列表文字,而caller
例如是一个函数,可以根据上下文返回列表或标量。在这样的行中:
...
看到标量上下文,因此如果...
是一个列表文字,那么您将在标量上下文中拥有一个列表文字:但是列表文字不会生成列表,因为它包含的逗号运算符会看到标量上下文,这会导致它返回列表文字的最后一项,并在评估剩余值后将其丢弃。
就函数而言,函数本身会看到调用它的任何上下文,然后将其传播到该函数返回的任何行。因此,您可以在标量、列表或 void 上下文中使用函数,并且如果该 sub 的最后一行恰好是列表文字,则该列表文字将看到这些上下文中的任何一个并且将表现得适当。
所以基本上这是一个术语区别,
listliteral
指的是实际源代码*中以逗号分隔的值列表,而list
指的是放置在Perl 的堆栈。您可以编写带有返回值的子例程,这些返回值的行为类似于数组或与上下文相关的列表文字。
*或产生逗号分隔值列表的内容,例如
qw()
或粗逗号=>
或哈希或数组切片。您还可以在这里查看我的答案:如何从 Perl 中返回数组的函数中获取第一项? 其中更详细地介绍了列表。
A list literal is something that is actually a list written out in code, so
(1, 2, 3)
is a list literal, whereascaller
for example is a function that could return a list or a scalar depending on context.In a line like:
the
...
sees scalar context, so if...
was a list literal, then you would have a list literal in scalar context:but the list literal does not result in a list, because the comma operator it contains sees scalar context, which then results in it returning the last item of the list literal, and throwing the remaining values away after evaluating them.
In terms of a function, the function itself sees whatever context it is called from, which then is propagated to any line in that function that returns. So you can have a function in scalar, list, or void context, and if the last line of that sub happens to be a list literal, that list literal will see any of those contexts and will behave appropriately.
So basically this is a terminology distinction, with
list literal
referring to a comma separated list of values in the actual source code*, andlist
referring to a sequence of values placed onto perl's stack.You can write subroutines with return values that either behave like arrays or like list literals with regard to context.
*or something that results in a list of comma separated values, like a
qw()
or a fat comma=>
or a hash or array slice.You can also look at my answer here: How do I get the first item from a function that returns an array in Perl? which goes into a bit more detail about lists.
我同意你和
perlfaq4
的观点。引用perldata
,这可能是关于这一点的明确文档:(强调我的)。
也就是说,池上有权使用他想要的任何术语。不同的人用不同的术语来思考不同的语言结构,只要最终结果是相同的,我认为他们的术语与文档中的术语不同并不重要。 (不过,在公共论坛上坚持使用特殊术语并不是一个好主意!)
I agree with you and with
perlfaq4
. To quoteperldata
, which is probably the definitive documentation on this point:(emphasis mine).
That said, ikegami is entitled to use whatever terminology (s)he wants. Different people think of different language constructs in different terms, and as long as the end results are the same, I don't think it matters if their terminology differs from that in the documentation. (It's not a great idea to insist on idiosyncratic terminology in a public forum, though!)
问问珀尔就知道了!
所以,是的,人们可以在标量上下文中拥有一个列表。
无法在标量上下文中返回列表。 (嗯,从 XS 是可能的,但程序会崩溃,可能会出现“奇怪的复制”错误。)
不可能是任何其他方式。如果存在不同的列表操作和逗号操作,则无法编译以下内容:
这会导致列表操作还是逗号操作?实际上,不存在这样的区别,所以是的,它会导致该操作。
Just ask Perl!
So yes, one can have a list in scalar context.
One cannot return a list in scalar context. (Well, it is possible from XS, but the program will crash, probably with a "Bizarre copy" error.)
It can't be any other way. If there was a distinct list op and comma op, it would be impossible to compile the following:
Would that result in a list op or a comma op? In reality, there is no such distinction, so yes, it results in that op.
这不是一个清单。由于您要分配给标量,因此它是逗号运算符 - 计算左侧,计算右侧,返回右侧,然后从左到右解析。
$scalar
将是'confused'
:)It's not a list. Since you're assigning to a scalar, it's the comma operator - evaluates the left side, evaluates the right side, returns the right side, and resolves left-to-right.
$scalar
will be'confused'
:)这是术语和观点的问题。这里的术语很棘手,因为您可以在源代码中编写列表,返回值列表,或评估列表上下文中的某些内容......并且“列表”一词在每种情况下的含义都略有不同!
从技术上讲,列表不能存在于标量上下文中,因为 perl(解释器)不会为如下内容创建值列表:
迂腐精确时,这被解释为标量中逗号运算符的行为语境。类似地,qw 被定义为返回标量上下文中的最后一个元素,因此这里也没有列表:在这两种情况下(以及我们可以收集的任何其他运算符示例)我们要做什么意思是解释器不会创建值列表。这是一个实现细节。 perl 没有理由不能创建一个值列表并丢弃除最后一个值之外的所有值;它只是选择不这样做。
Perl 语言是抽象的。在源代码级别
('a', 'b', 'c')
是一个列表。您可以在对其施加标量上下文的表达式中使用该列表,因此从这个角度来看,列表可以存在于标量上下文中。最后,这是在[Pp]erl如何运作的心智模型之间进行选择。 “标量上下文中的列表返回其最后一个值”模型稍微不准确,但更容易理解。据我所知,不存在任何功能不正确的极端情况。 “标量上下文中不存在列表”模型更准确,但更难使用,因为您需要考虑标量上下文中每个运算符的行为。
It's a matter of terminology and perspective. Terminology is tricky here because you can write a list in source code, return a list of values, or evaluate something in list context.. and the word "list" means something subtly different in each case!
Technically, a list cannot exist in scalar context because perl (the interpreter) does not create a list of values for things like this:
When being
pedanticprecise this is explained as the behavior of the comma operator in scalar context. Similarly,qw
is defined as returning the last element in scalar context so there's no list here, either:In both of these cases (and for any other operator examples that we could muster up) what we're saying is that the interpreter doesn't create a list of values. That's an implementation detail. There's no reason that perl couldn't create a list of values and throw away all but the last one; it just chooses not to.
Perl the language is abstract. At a source code level
('a', 'b', 'c')
is a list. You can use that list in an expression that imposes scalar context on it, so from that perspective a list can exist in scalar context.In the end, it's a choice between mental models of how [Pp]erl operates. The "A list in scalar context returns its last value" model is slightly inaccurate but easier to grok. As far as I know there aren't any corner cases where it is functionally incorrect. The "There's no such thing as a list in scalar context" model is more accurate but harder to work with as you need to consider the behavior of every operator in scalar context.
如果您相信标量上下文中的列表,请拍拍手
If you believe in Lists in Scalar Context, Clap your Hands