空列表可以在标量上下文中吗?

发布于 2024-11-28 09:34:19 字数 704 浏览 0 评论 0原文

有一个谎言,标量上下文中的列表会产生列表的最后一个元素。这是一个谎言,因为(正如俗话所说)你不能在标量上下文中拥有一个列表。在标量上下文中看起来像列表的实际上是标量上下文中的逗号运算符,并且它在标量上下文中具有不同的行为。

然而,这个逻辑似乎有一个漏洞:空列表(有时称为空列表)。字符 ()定义为空列表 perldoc perlglossary。该构造

my $s = ();

是有效的代码,并将 undef 返回到 $s。这似乎没有在 perldoc 中的任何地方记录(我还没有检查 Camel),但是很多代码都依赖它,所以我认为它会保留下来。

现在序言已经完成,问题是:如果我们在标量上下文中不能有一个列表,那么我们在标量上下文中将空列表称为什么以及不将其称为列表的理由是什么(因为没有逗号)在标量环境中)?

如果您喜欢这个问题,您可能还会喜欢 P5P 中正在进行的讨论

There is a lie that a list in scalar context yields the last element of the list. This is a lie because (as the saying goes) you can't have a list in scalar context. What looks like a list in scalar context is really the comma operator in scalar context and it has different behavior in scalar context.

However, there seems to be a loop hole in this logic: the null list (sometimes called the empty list). The characters () are defined to be the null list by perldoc perlglossary. The construct

my $s = ();

is valid code and returns undef to $s. This does not appear to be documented anywhere in perldoc (I haven't checked the Camel), but lots of code counts on it, so I think it is here to stay.

Now that the preamble is done, here is the question: if we cannot have a list in scalar context, then what do we call the empty list in scalar context and what is the rational for not calling it a list (since there are no commas to be in scalar context)?

If you are enjoying this question, you may also like the discussion going on in P5P.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

离旧人 2024-12-05 09:34:20

列表是一个非常通用的词。您可能指的是列表运算符或列表值。

代码中没有逗号,因此没有列表运算符。

代码中没有列表上下文,因此没有列表值。

因此,括号中没有列表

my $s = ();

永远不会创建列表

(仅在赋值运算符的 LHS 上间接创建。)

我们在标量上下文中将空列表称为什么

Perl 将其称为“存根”(如下所示),事实确实如此。它是代码中的一个占位符,实际上不允许放置任何内容。

存根由“空括号”表示,因此这是它的另一个名称。

我称之为糟糕的代码。如果要分配undef,请分配undef

有一个谎言,标量上下文中的列表会产生列表的最后一个元素。

不,确实如此。列表值不能存在于标量上下文中,因此只剩下列表运算符。

列表运算符也称为逗号运算符,返回标量上下文中列表的最后一个元素。


比较以下内容。未提及列表:

>perl -MO=Concise -e"my $s = ();"
6  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
5     <2> sassign vKS/2 ->6
3        <0> stub sP ->4
4        <0> padsv[$s:1,2] sRM*/LVINTRO ->5
-e syntax OK

提及了列表

>perl -MO=Concise -e"my @a = ();"
7  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
6     <2> aassign[t2] vKS ->7
-        <1> ex-list lK ->4
3           <0> pushmark s ->4
-           <0> stub lP ->-
-        <1> ex-list lK ->6
4           <0> pushmark s ->5
5           <0> padav[@a:1,2] lRM*/LVINTRO ->6
-e syntax OK

...并且与括号无关

>perl -MO=Concise -e"my @a = 's';"
8  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
7     <2> aassign[t2] vKS ->8
-        <1> ex-list lK ->5
3           <0> pushmark s ->4
4           <
gt; const[PV "s"] s ->5
-        <1> ex-list lK ->7
5           <0> pushmark s ->6
6           <0> padav[@a:1,2] lRM*/LVINTRO ->7
-e syntax OK

List is a very generic word. You could possibly be referring to the list operator or to a list value.

There is no comma in the code, so there is no list operator.

There is no list context in the code, so there is no list value.

Therefore, there is no list in

my $s = ();

Parentheses never create a list

(Only indirectly when on the LHS of an assignment operator.)

what do we call the empty list in scalar context

Perl calls it a "stub" (as shown below), and that's truly what it is. It's a placeholder in the code where putting literally nothing would be disallowed.

The stub is represented by "empty parentheses", so that's another name for it.

I call it bad code. If you want to assign undef, assign undef.

There is a lie that a list in scalar context yields the last element of the list.

No, that's true. List values cannot exist in scalar context, so that leaves the list operator.

The list operator aka the comma operator returns the last element of the list in scalar context.


Compare the following. No mention of list:

>perl -MO=Concise -e"my $s = ();"
6  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
5     <2> sassign vKS/2 ->6
3        <0> stub sP ->4
4        <0> padsv[$s:1,2] sRM*/LVINTRO ->5
-e syntax OK

There is a mention of a list

>perl -MO=Concise -e"my @a = ();"
7  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
6     <2> aassign[t2] vKS ->7
-        <1> ex-list lK ->4
3           <0> pushmark s ->4
-           <0> stub lP ->-
-        <1> ex-list lK ->6
4           <0> pushmark s ->5
5           <0> padav[@a:1,2] lRM*/LVINTRO ->6
-e syntax OK

...and it has nothing to do with the parens

>perl -MO=Concise -e"my @a = 's';"
8  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
7     <2> aassign[t2] vKS ->8
-        <1> ex-list lK ->5
3           <0> pushmark s ->4
4           <
gt; const[PV "s"] s ->5
-        <1> ex-list lK ->7
5           <0> pushmark s ->6
6           <0> padav[@a:1,2] lRM*/LVINTRO ->7
-e syntax OK
眼眸 2024-12-05 09:34:20

它更像是一个无值表达式,相当于undef。更多示例:

$ perl -we 'print scalar( () )'
Use of uninitialized value in print at -e line 1.

$ perl -we 'print 0+()'
Use of uninitialized value in addition (+) at -e line 1.

It's more like a valueless expression which is equivalent to undef. Some more examples:

$ perl -we 'print scalar( () )'
Use of uninitialized value in print at -e line 1.

$ perl -we 'print 0+()'
Use of uninitialized value in addition (+) at -e line 1.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文