Scala:方法\运算符重载 [英] Scala: method\operator overloading
问题描述
以下示例来自《Scala 编程》一书.给定一个Rational"类和以下方法定义:
The following example is from the book 'Programming in Scala'. Given a class 'Rational' and the following method definition:
def add(that: Rational): Rational =
new Rational(
this.numer * that.denom + that.numer * this.denom,
this.denom * that.denom
)
我可以使用接受 Int 参数的便捷版本成功重载 add 方法,并且利用上面的定义:
I can successfully overload the add method with a convenience version that takes an Int argument, and makes use of the definition above:
def add(that: Int): Rational =
add(new Rational(that, 1))
目前没有问题.
现在,如果我将方法名称更改为操作符样式名称:
Now, if I change the method name to an operator style name:
def +(that: Rational): Rational =
new Rational(
this.numer * that.denom + that.numer * this.denom,
this.denom * that.denom
)
像这样重载:
def +(that: Int): Rational =
+(new Rational(that, 1))
我收到以下编译错误:
(fragment of Rational.scala):19: error: value unary_+ is not a member of this.Rational
+(new Rational(that, 1))
^
为什么编译器要寻找 +
方法的一元版本?
Why is the compiler looking for a unary version of the +
method?
推荐答案
在 Scala 中,+x
、-x
、~x 类型的任何构造
和 !x
被转换为方法调用 x.unary_+
等.这部分是为了允许类似 Java 的语法具有 !b
作为布尔值 b
的否定,或者 -x
作为数字 x
的否定.
In Scala, any construct of the type +x
, -x
, ~x
and !x
is transformed into a method call x.unary_+
, etc. This is partially to allow Java-like syntax of having !b
as the negation of the boolean b
, or -x
as the negation of the number x
.
因此,代码片段 +(new Rational(that, 1))
被翻译成 (new Rational(that,1)).unary_+
,并作为Rational
没有这个方法,你会得到一个编译错误.仅当您的函数被调用 +
、-
、~
或 !
时,您才会收到此错误,因为这些是Scala 只允许将字符用作一元运算符.例如,如果您调用函数 @+
,则代码编译得很好.
Therefore, the code snippet +(new Rational(that, 1))
is translated into (new Rational(that,1)).unary_+
, and as Rational
doesn't have this method, you get a compile error. You will get this error only if your function is called +
, -
, ~
or !
as these are the only characters Scala allows as unary operators. For example, if you called your function @+
, the code compiles just fine.
不过,我建议将重写的 add 函数编写为:
Though, I would suggest writing the overridden add function as:
def +(that: Int): Rational =
this + (new Rational(that, 1))
这段代码更好地展示了你的函数的意图——你添加了一个新的Rational
,它由一个整数作为分子和1
作为分母构造到this代码>.这种写法被翻译成
this.+(new Rational(that, 1))
,这就是你想要的——在this上调用
+
函数代码>.
This code shows the intent of your function better -- you add a new Rational
constructed from an integer as a numerator and 1
as denominator to this
. This way of writing gets translated into this.+(new Rational(that, 1))
, which is what you want -- invoking the +
function on this
.
请注意,您可以使用中缀表示法,但是该函数被调用.例如,如果您将名称改回 add
,您仍然可以保持定义为:
Note that you can use the infix notation however the function is called. For example, if you change the name back to add
, you can still keep the definition as:
def add(that: Int): Rational =
this add (new Rational(that, 1))
这篇关于Scala:方法\运算符重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!