23.5. Adnotacja tailrec
Adnotacja scala.annotation.tailrec służy do oznaczania metod. Jeśli metoda oznaczona tą adnotacją nie może być zoptymalizowana za pomocą optymalizacji ogonowej, to kompilator powinien wygenerować komunikat o błędzie.
Plik TailRecLoops.scala: import scala.annotation.tailrec class TailRecLoops { @tailrec final def repeat1(n: Int, body: => Unit) { if (n > 1) repeat1(n-1, body) body } @tailrec def repeat2(n: Int, body: => Unit) { body if (n > 1) repeat2(n-1, body) } }
Kompilacja obiektu TailRecLoops z pliku TailRecLoops.scala nie udaje się.
$ scalac TailRecLoops.scala
TailRecLoops.scala:6: error: could not optimize @tailrec annotated method repeat1: it contains a recursive call not in tail position
body
^
TailRecLoops.scala:9: error: could not optimize @tailrec annotated method repeat2: it is neither private nor final so can be overridden
def repeat2(n: Int, body: => Unit) {
^
two errors found
Metoda repeat1 jest oznaczona adnotacją tailrec, ale nie może zostać zoptymalizowana, gdyż zawiera wywołanie rekurencyjne, które nie jest w pozycji ogonowej. Metoda repeat2 jest oznaczona adnotacją tailrec, ale nie może zostać zoptymalizowana, gdyż może zostać nadpisana w klasie pochodnej.
Plik TailRecLoops.scala:
import scala.annotation.tailrec
class TailRecLoops {
@tailrec
final def repeat1(n: Int, body: => Unit) {
if (n > 1) repeat1(n-1, body)
body
}
@tailrec
def repeat2(n: Int, body: => Unit) {
body
if (n > 1) repeat2(n-1, body)
}
}
