我知道你可以重载一个已有的操作符,但我想知道是否可能创建一个新的操作符。以下是我的场景:
我希望实现这个功能:
var x = (y < z) ? y : z;
要与此等效:
var x = y <? z;
换言之,我想创建自己的<?
运算符。
不,这是不可能的。您需要创建一个方法来实现。
如其他答案所述,您无法创建新的运算符 - 至少,不会在不更改编译器内置的词法分析器和语法分析器的情况下。基本上,编译器被构建为识别单个字符(如<
或?
)或一对字符(如>>
或<=
)作为运算符,并进行特殊处理;它知道i<5
是表达式而不是变量名,例如。将运算符识别为运算符是与决定运算符实际执行的过程分开的过程,并且与编译器紧密集成 - 这就是您可以自定义后者但无法自定义前者的原因。
对于具有开源编译器的语言(如GCC),你理论上可以修改编译器以识别新的运算符。但这并不容易,而且此外,每个人都需要使用您的自定义编译器才能使用您的代码。
我很惊讶没有人提到"运算顺序"。
当编译器评估一个表达式时,必须考虑以正确的顺序执行操作,这样在表达式中相同的“级别”上,乘法始终在加法之前执行,例如(1+2*3)=(2*3+1)
。
当您重载运算符时,可以更改运算符的功能,但不能更改编译器评估它的顺序。如果您创建了新的运算符,则无法告诉编译器与其他运算符相比评估它的顺序。因此,如果您写 x <? 2 + 5
,是先执行x <? 2
然后加5还是先执行加法然后再做x <? 7
无从得知。
不仅你不能这样做,而且你为什么想这样做呢?
我不确定您的 y 和 z 是什么类型,但如果它们是数字类型,您可以尝试使用:
var x = Math.Min(y, z);
var x = (y < z) ? y : z;
但我有点成为“?:狂热者”。
好的代码不仅紧凑高效,而且易读。即使您是唯一阅读它的人,某天您也会回来看到那个<?
运算符并想知道它到底是做什么的。
====
,这样我的整个开发团队都知道我们正在为该特定对象使用覆盖的测试。就这样,但是,是的...我只是想避免在if语句中使用方法...只是闲逛。 - Piotr Kulay.MethodName(z)
你可以尝试重载其他运算符,如%
或+
,以充当<?
运算符。
会很有趣的。
implicit class <?(y: Int) { def <?(z: Int) = y min z }
-- 这是一个隐式类,用于向Int
添加一个方法,然后是方法本身。_这个_特定的方法不起作用,因为<?
是一个xml-start关键字。 - Daniel C. SobralMin(y, z)
)难以阅读得多。 - Thomas Levesque