Существуют различные ответы о переполнении стека, которые объясняют условия, при которых возможна хвостовая рекурсия в Scala .Я понимаю ограничения и как и где я могу воспользоваться хвостовой рекурсией.Часть, которую я не понимаю, заключается в том, почему существует ограничение на частные или конечные методы.
Я не исследовал, как компилятор Scala на самом деле преобразует рекурсивную функцию в нерекурсивную на уровне байт-кода, нодавайте предположим, что он делает что-то вроде следующего.У меня есть класс Foo
с рекурсивной функцией mod
:
class Foo {
def mod(value: Int, denom: Int): Int = {
if(denom <= 0 || value <= 0) 0
else if(0 <= value && value < denom) value
else mod(value - denom, denom)
}
}
Это базовая функция по модулю, которая, как мне кажется, компилятор Scala переводит в какую-то псевдо-Java-Scala, например:
class Foo {
def mod(value: Int, denom: Int): Int = {
if(denom <= 0 || value <= 0) return 0
while(value > denom) value -= denom
return value
}
}
(я могу поверить, что я испортил этот перевод, но я не думаю, что детали важны ..)
Так что теперь предположим, что я подкласс Foo
:
class Bar extends Foo {
def mod(value:Int, denom: Int): Int = 1
}
Что мешает этому работать?Когда у JVM есть Foo/Bar
и вызывается mod
, почему возникает проблема с разрешением функции mod
, которую следует использовать.Почему это отличается от ситуации, когда базовая функция нерекурсивна?
Вот несколько возможных причин, по которым я вижу это:
дляпо какой-то причине реализация компилятора Scala не справляется с этим (достаточно справедливо, если это так. Если да, есть ли планы изменить это?)
в Foo
mod
функция превращается в mod-non-recursive
во время компиляции, поэтому Foo
на самом деле не имеет mod
метода для переопределения.