Perl递增还是递减,但不是两者都递增?

Perl递增还是递减,但不是两者都递增?,perl,syntax,increment,decrement,Perl,Syntax,Increment,Decrement,在其中一些问题上,我可以理解为什么-$a没有歧义,也没有优先冲突。拉里不让我这么做,我真是受够了。。甚至不要让我开始找楼层操作员 我并不需要也不想这样做——我只是想更多地了解这些运算符是如何工作的,并发现了那种令人惊讶的结果。例如,您希望得到什么: $a++; # ok $a--; # ok --$a; # ok ++$a; # ok --$a++; # syntax error $a++--; # syntax error ($a++)--; # syn

在其中一些问题上,我可以理解为什么-$a没有歧义,也没有优先冲突。拉里不让我这么做,我真是受够了。。甚至不要让我开始找楼层操作员


我并不需要也不想这样做——我只是想更多地了解这些运算符是如何工作的,并发现了那种令人惊讶的结果。

例如,您希望得到什么:

$a++;     # ok
$a--;     # ok
--$a;     # ok
++$a;     # ok
--$a++;   # syntax error
$a++--;   # syntax error
($a++)--; # syntax error
--$a--;   # syntax error
我想很难解释$b等于0,$a等于1,不是吗?。。。在任何情况下,我都不记得有哪一个真正的例子可以使用这种语法。它毫无用处,丑陋不堪,我们发现:

++和-在C中一样工作

在同一页稍早的地方

Perl运算符具有以下关联性和优先级,从最高优先级到最低优先级依次列出。从C中借用的运算符彼此之间保持相同的优先级关系,即使C的优先级有点扭曲。这使C语言的人更容易学习Perl


因为C在这两种情况下都返回一个右值,所以Perl执行相同的操作。有趣的是,C++返回一个LV值的引用,用于预增量/减量,从而具有不同的语义。
$a = 1;
$b = --$a++;   # imaginary syntax
就像+++$a一样,不存在歧义,不存在优先级冲突,而且它完全不需要代码来运行。这种限制完全是人为的[1],这意味着专门添加了代码来禁止它

那么为什么长度为$x=123;不允许?因为不允许它允许我们抓住错误,几乎没有负面影响

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在没有左值检查的情况下正常工作

++$a = 123;              # XXX Did you mean "++$a == 123"?
更改+++$a以返回左值将允许+++$a工作,但也将允许+++$a=123工作。什么更有可能++$a=123是故意的,或者+++$a=123是+++$a==123的打字错误

下面显示了length$x=123在没有左值语法检查的情况下可以工作

$ 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中的值并返回新值,然后从存储在$a中的值中减去一个。嗯,$a+1可以为您节省两个字符、两次写入内存和几个处理器周期。可维护性的提高也不会有什么坏处……Perl在POSIX.pmIt中有一个底线,它可能很难想象具有类似于普通编程语法的实际应用程序,但在我的世界里,我编写的Perl编写的Perl更多,我很容易遇到这样的情况:我可能是++或-一个子句,pre或post。编写它可能比回过头来查看它之前是否被减量等更容易。perl还返回pre的左值,尽管它不能直接用于assignment@ysth,根据您的定义,在Perl中,每个运算符都返回一个左值。这是一个无用的定义。更有用的是,定义返回的左值与返回的左值一样标记;这是一个明确的句法问题。在OSCON,我们将与Randal、John Orwant以及Perl大师MJD一起讨论这些语法建议。我认为一些Perl专家在这一级别上进行了研究,这就是我在这里提出这个问题的原因。我很抱歉。假设这是可能的,我希望$a能回到原来的价值,$b能持有$a-1。但是,正如前面所指出的,-和++返回变量的值,而不是变量本身,因此对$a应用,-将返回常量0,然后我们将尝试应用++,从而导致错误。
$ 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