重载方法上的Scala类型推断

重载方法上的Scala类型推断,scala,type-inference,Scala,Type Inference,鉴于此代码: class Rational(n: Int, d: Int) { require(d != 0) private val g = gcd(n.abs, d.abs) val numerator = n / g val denominator = d / g def this(n: Int) = this(n, 1) override def toString = numerator + "/" + denominator def +(r: Rati

鉴于此代码:

class Rational(n: Int, d: Int) {
  require(d != 0)
  private val g = gcd(n.abs, d.abs)
  val numerator = n / g
  val denominator = d / g

  def this(n: Int) = this(n, 1)

  override def toString = numerator + "/" + denominator

  def +(r: Rational) = new Rational(numerator * r.denominator + r.numerator * denominator, denominator * r.denominator)

  def *(r: Rational) = new Rational(numerator * r.numerator, denominator * r.denominator)

  def +(i: Int) = new Rational(i) + this

  private def gcd(a: Int, b: Int) : Int = {
    if (b == 0) a else gcd(b, a % b)
  }

}
为什么scala不能推断+(i:Int)返回一个有理数?(fsc给出
重载方法+需要结果类型
错误)

如果我将该方法更改为:

def +(i: Int): Rational = { new Rational(i) + this }

我在scala邮件列表中找到了一个问题完全相同的线程。这里的答案解释了为什么需要给出返回类型。在进一步调查之后,我还发现了这个:。请允许我引用其中的答案:

当需要显式类型注释时。

实际上,您必须为以下情况提供显式类型注释:

方法在以下情况下返回值:

  • 在方法中显式调用return时(即使在末尾)
  • 当一个方法是递归的
  • 当一个方法重载且其中一个方法调用另一个方法时。调用方法需要返回类型注释。
  • 当推断的返回类型比您预期的更一般时,例如,
    Any

在这种情况下,它可以推断出正确的类型,但它还不够聪明。很容易用重载方法构造一些病态的示例,这些示例会变得非常混乱,所以我想这就是Scala团队决定明确要求返回类型的原因。这类似于递归方法,在递归方法中,您也需要结果类型,即使编译器在许多情况下可以推断出结果类型