Perl 中的逗号是否在所有上下文中都具有关联性?

Is the comma in Perl associative in all contexts?

提问人:fmg 提问时间:4/3/2023 最后编辑:ikegamifmg 更新时间:4/4/2023 访问量:71

问:

假设 、 和 是不涉及优先级高于逗号的运算符的表达式。表达式和等价物是否在标量、列表和/或 void 上下文中?更准确地说,您能否在不影响程序执行的情况下始终替换为,反之亦然?EFG((E, F), G)(E, (F, G))((E, F), G)(E, (F, G))

Perl 表达式 运算符优先级 关联性

评论


答:

4赞 ikegami 4/4/2023 #1

上下文不会影响代码的分析方式。

逗号/列表运算符保证从左到右计算每个操作数(无论上下文如何)。

从这一点和更多的信息中,我们可以证明 ,并且是等价的。[1]E, F, G( E, F ), GE, ( F, G )


既然你特别提到了上下文,我们将更详细地研究它。

对于 void、list 或 indeterminate[2] 上下文 c,我们在所有情况下都为每个项目获得相同的上下文 c

   c               c                 c
-------       -----------       -----------
c  c  c          c      c       c     c
-  -  -       --------  -       -  --------
                c  c                 c  c
                -  -                 -  -
E, F, G       ( E, F ), G       E, ( F, G )

对于标量上下文 (s),在所有情况下,除了最后一项之外,我们都会得到 void 上下文 (v)。

   s               s                 s
-------       -----------       -----------
v  v  s          v      s       v     s
-  -  -       --------  -       -  --------
                v  v                 v  s
                -  -                 -  -
E, F, G       ( E, F ), G       E, ( F, G )

  1. 我很想说它们的编译方式相同,但事实并非如此。尽管文档说它是一个二进制运算符,但它是作为 n 元运算符实现的。parens 会导致创建运算符的另一个实例(在您的示例中有效地使其成为二进制运算符)。

  2. 当它是 sub 的最后一个表达式时,上下文仅在运行时已知,我称之为“不确定”。除了标量上下文中的列表/逗号运算符外,这没有任何区别。运行时上下文会传播到每个操作数,因此,如果仅在运行时知道 s,s,s,s,则获得 s,s,尽管如果上下文在编译时已知,则获得 v,v,s

    正如你在上面看到的,这并不影响答案。,并且无论上下文在编译时是否已知,都是等效的。E, F, G( E, F ), GE, ( F, G )