Scala вывод типа при перегруженном методе
С учетом этого кода:
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) возвращает Rational? (fsc дает ошибку overloaded method + needs result type
)
если я изменил этот метод на:
def +(i: Int): Rational = { new Rational(i) + this }
Он работает...
Ответы
Ответ 1
Я нашел поток в списке рассылки scala с точно таким же вопросом здесь. Ответы там немного объясняют, почему требуется указать тип возврата. Изучив еще немного, я также нашел следующее: Когда тип возврата требуется для методов в Scala. Если я должен процитировать ответ оттуда:
Когда требуются аннотации явного типа.
В практическом плане вы должны предоставить явные аннотации типов для следующих ситуаций:
Возвращает значения метода в следующих случаях:
- Когда вы явно вызываете return в методе (даже в конце).
- Когда метод рекурсивный.
- Когда метод перегружен и один из методов вызывает другой. Вызывающий метод требует аннотации типа возвращаемого значения.
- Когда тип возвращаемого возврата будет более общим, чем вы предполагали, например,
Any
.
Ответ 2
В этом случае он может вывести правильный тип, но он просто недостаточно умен. Легко построить некоторые патологические примеры с перегруженными методами, когда ситуация становится очень запутанной, поэтому я думаю, что команда Scala решила сделать четкий разрез и потребовать тип возврата. Это похоже на рекурсивные методы, в которых вам нужен тип результата, даже если компилятор мог его вывести во многих случаях.