Scala:方法\运算符重载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1991240/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 01:49:26  来源:igfitidea点击:

Scala: method\operator overloading

scala

提问by jason

The following example is from the book 'Programming in Scala'. Given a class 'Rational' and the following method definition:

下面的例子来自'Programming in Scala'一书。给定一个“Rational”类和以下方法定义:

def add(that: Rational): Rational =
    new Rational(
        this.numer * that.denom + that.numer * this.denom,
        this.denom * that.denom
    )

I can successfully overload the add method with a convenience version that takes an Int argument, and makes use of the definition above:

我可以使用接受 Int 参数的便捷版本成功重载 add 方法,并使用上面的定义

def add(that: Int): Rational =
    add(new Rational(that, 1))

No problems so far.

到目前为止没有问题。

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
    )

And overload like so:

并像这样重载:

def +(that: Int): Rational =
    +(new Rational(that, 1))

I get the following compile error:

我收到以下编译错误:

(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?

为什么编译器要寻找该+方法的一元版本?

回答by Flaviu Cipcigan

In Scala, any construct of the type +x, -x, ~xand !xis transformed into a method call x.unary_+, etc. This is partially to allow Java-like syntax of having !bas the negation of the boolean b, or -xas the negation of the number x.

在Scala中,所述类型的任何构建体+x-x~x!x被变换成一个方法调用x.unary_+,等等,这是部分地允许Java类具有语法!b作为布尔的否定b,或-x作为数的否定x

Therefore, the code snippet +(new Rational(that, 1))is translated into (new Rational(that,1)).unary_+, and as Rationaldoesn'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.

因此,代码片段+(new Rational(that, 1))被翻译成(new Rational(that,1)).unary_+,由于Rational没有这个方法,你会得到一个编译错误。仅当您的函数被调用时+,您才会收到此错误-~!因为这些是 Scala 允许作为一元运算符的唯一字符。例如,如果您调用了您的函数@+,则代码编译得很好。

Though, I would suggest writing the overridden add function as:

不过,我建议将重写的 add 函数编写为:

def +(that: Int): Rational =
  this + (new Rational(that, 1))

This code shows the intent of your function better -- you add a new Rationalconstructed from an integer as a numerator and 1as 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.

此代码更好地显示了您的函数的意图——您添加了一个Rational由整数构造的新函数作为分子和1分母this。这种写法被翻译成this.+(new Rational(that, 1)),这就是你想要的——调用+函数this

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:

请注意,您可以使用中缀表示法,但是该函数被调用。例如,如果您将名称改回add,您仍然可以将定义保留为:

def add(that: Int): Rational =
  this add (new Rational(that, 1))

回答by Mushtaq Ahmed

If you call +with explicit this, it should work

如果您+使用显式调用this,它应该可以工作

def +(that: Int): Rational = this.+(new Rational(that, 1))

Scala allows to define unary operators that can be used in prefix operator notation. For example you can use +as a prefix operator to achieve the same:

Scala 允许定义可用于前缀运算符符号的一元运算符。例如,您可以使用+前缀运算符来实现相同的目的:

def unary_+: Rational = this.+(new Rational(that, 1))
val a = new Rational(3,2)
val b = +a

Without explicit thisin your example, the compiler thinks that you are using unary operator +which is not defined.

this在您的示例中没有明确,编译器认为您使用的+是未定义的一元运算符。

回答by kikibobo

You haven't specified the binary + operator, you've specified the unary + operator.

您尚未指定二元 + 运算符,而是指定了一元 + 运算符。

So instead of:

所以而不是:

def +(that: Int): Rational =
  +(new Rational(that, 1))

You need to write this:

你需要这样写:

def +(that: Int): Rational =
  this +(new Rational(that, 1))