【问题标题】:Perl increment or decrement, but not both?Perl 递增或递减,但不能两者兼而有之?
【发布时间】:2014-07-30 17:12:34
【问题描述】:
$a++;     # ok
$a--;     # ok
--$a;     # ok
++$a;     # ok
--$a++;   # syntax error
$a++--;   # syntax error
($a++)--; # syntax error
--$a--;   # syntax error

在其中一些方面,我可以看出原因——但在 --$a-- 这样的情况下,没有歧义,也没有优先级冲突。我很生气拉里没有让我这样做..(甚至没有让我开始因为缺乏地板操作员!)

不是我需要或想要的——我只是想更多地了解这些操作员的工作原理,并发现了那种令人惊讶的结果..

【问题讨论】:

  • 可能是因为++$a--.. 的语义不健全。
  • ++$a--:将 $a 中存储的值加一并返回新值,然后将 $a 中存储的值减一。嗯,$a+1 为您节省了两个字符、两次写入内存和几个处理器周期。在可维护性方面的收益也不会受到伤害......
  • Perl 在 POSIX.pm 中带有 floor
  • 可能很难想象与行人编程类似的语法的实际应用,但在我的世界中,我编写的 Perl 编写了更多的 Perl,我很容易遇到这样的情况,我可能会 ++ 或-- 一个子句,前或后。对它进行编程可能比回顾它以前是否被递减等更容易。

标签: perl syntax increment decrement


【解决方案1】:

Perldoc for auto increment/decrement 我们发现:

“++”和“--”在 C 中工作。

在同一页面上稍早

Perl 运算符具有以下关联性和优先级,从最高优先级到最低优先级列出。从 C 中借用的运算符彼此保持相同的优先级关系,即使 C 的优先级稍有混乱。 (这让 C 语言的人更容易学习 Perl。)

由于 C 在这两种情况下都返回一个 rvalue,Perl 也是如此。有趣的是,C++ 返回一个对 lvalue 的引用以进行预增/减量,因此具有不同的语义。

【讨论】:

  • perl 还为 pre- 返回一个左值(虽然不能用于直接赋值)
  • @ysth,根据您的定义,每个运算符在 Perl 中都返回一个左值。这是一个无用的定义。将“返回左值”定义为“标记为返回左值”会更有用。
【解决方案2】:

考虑以下几点:

length($x) = 123;

就像++(++$a) 一样,没有歧义,没有优先级冲突,并且绝对不需要代码来运行。这个限制完全是人为的[1],也就是说专门加了代码来禁止它!

那么为什么length($x) = 123; 是不允许的?因为禁止它可以让我们捕获错误而几乎没有缺点。

length($x) = 123;        # XXX Did you mean "length($x) == 123"?

如何禁止?使用左值的概念。左值是允许出现在标量赋值左侧的值。

一些运算符被认为返回左值。

$x = 123;                # $x returns an lvalue
$#a = 123;               # $#a returns an lvalue
substr($s,0,0) = "abc";  # substr returns an lvalue

一些参数应该是左值。

length($x) = 123;        # XXX LHS of scalar assignment must be an lvalue
++length($x);            # XXX Operand of pre/post-inc/dec must be an lvalue.

前/后自增/自减运算符未标记为返回左值。除了左值之外的运算符将不接受它们。

++$a = 123;              # XXX Did you mean "++$a == 123"?

这也有防止++(++$a) 在没有左值检查的情况下正常工作的副作用。

$ perl -E'                              ++(      ++$a); say $a;'
Can't modify preincrement (++) in preincrement (++) at -e line 1, near ");"
Execution of -e aborted due to compilation errors.

$ perl -E'sub lvalue :lvalue { $_[0] }  ++lvalue(++$a); say $a;'
2

++$a 更改为返回左值将允许++(++$a) 工作,但它也允许++$a = 123 工作。更有可能的是什么? ++$a = 123 是故意的,或者++$a = 123++$a == 123 的拼写错误?


  1. 以下显示length($x) = 123 可以在没有左值语法检查的情况下工作。

    $ perl -E'                              say length($x) = 123;'
    Can't modify length in scalar assignment at -e line 1, near "123;"
    Execution of -e aborted due to compilation errors.
    
    $ perl -E'sub lvalue :lvalue { $_[0] }  say lvalue(length($x)) = 123;'
    123
    

    您看到的打印值是length 在赋值更改后返回的标量值。

【讨论】:

    【解决方案3】:

    例如,你期望什么:

    $a = 1;
    $b = --$a++;   # imaginary syntax
    

    我认为很难解释 $b 等于 0 和 $a 是 1,不是吗?...无论如何,我不记得有任何实际示例表明该语法会很有用.又没用又丑

    【讨论】:

    • 我从来没有说过它是或实用的;这具体是一个句法问题。在 OSCON,我们会与 Randal、John Orwant,当然还有 Perl Master MJD 本人一起讨论这些语法建议。我认为该级别的一些 Perl 专家对此很感兴趣,这就是我在这里问它的原因。我很抱歉。
    • 假设有可能我希望$a 恢复到原来的值,而$b 保持$a-1。但是,正如已经指出的那样, -- 和 ++ 返回变量的值,而不是变量本身,因此将 -- 应用于 $a 将返回常量 0,然后我们将尝试对其应用 ++,结果出错了。
    猜你喜欢
    • 2011-06-17
    • 2015-10-14
    • 2017-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-10
    • 2018-12-01
    • 2020-02-04
    相关资源
    最近更新 更多