重载方法的 Scala 类型推断

发布于 2024-12-10 20:40:21 字数 802 浏览 0 评论 0原文

给出这段代码:

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 }

它有效...

Given this code:

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)
  }

}

why isn't scala able to infer that +(i: Int) returns a Rational number? (fsc gives overloaded method + needs result type error)

if i change that method to:

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

It works...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空气里的味道 2024-12-17 20:40:21

我在 scala 邮件列表中找到了一个具有完全相同问题的线程 此处。那里的答案解释了为什么需要给出返回类型。经过更多调查后,我还发现了这一点: Scala 中的方法何时需要返回类型。如果我应该引用那里的答案:

何时需要显式类型注释。

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

以下情况下方法返回值:

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

I found a thread in the scala mailing list with exactly the same question here. The answers there explains a bit why is it required to give the return type. After investigating a bit more I also found this: When is a return type required for methods in Scala. If I should quote the answer from there:

When Explicit Type Annotations Are Required.

In practical terms, you have to provide explicit type annotations for the following situations:

Method return values in the following cases:

  • When you explicitly call return in a method (even at the end).
  • When a method is recursive.
  • When a method is overloaded and one of the methods calls another. The calling method needs a return type annotation.
  • When the inferred return type would be more general than you intended, e.g., Any.
忆梦 2024-12-17 20:40:21

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

In this case it could infer the right type, but it just isn't clever enough. It's easy to construct some pathological examples with overloaded methods where things get really messy, so I guess that's why the Scala team decided to make a clear cut and require the return type. This is similar to recursive methods, where you need the result type, too, even though the compiler could infer it in many cases.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文