Adnotacja jest scala.annotation.tailrec
. Wywołuje błąd kompilatora, jeśli metoda nie może zostać zoptymalizowana pod kątem wywołań tail, co dzieje się, gdy:
- Wywołanie rekurencyjne nie znajduje się w końcowej pozycji
- Metoda może zostać zastąpiona
- Metoda nie jest ostateczna (szczególny przypadek poprzedniego)
Jest umieszczany tuż przed def
definicją metody. Działa w REPL.
Tutaj importujemy adnotację i próbujemy oznaczyć metodę jako @tailrec
.
scala> import annotation.tailrec
import annotation.tailrec
scala> @tailrec def length(as: List[_]): Int = as match {
| case Nil => 0
| case head :: tail => 1 + length(tail)
| }
<console>:7: error: could not optimize @tailrec annotated method: it contains a recursive call not in tail position
@tailrec def length(as: List[_]): Int = as match {
^
Ups! Ostatnie wezwanie brzmi 1.+()
: nie length()
! Sformułujmy ponownie metodę:
scala> def length(as: List[_]): Int = {
| @tailrec def length0(as: List[_], tally: Int = 0): Int = as match {
| case Nil => tally
| case head :: tail => length0(tail, tally + 1)
| }
| length0(as)
| }
length: (as: List[_])Int
Zauważ, że length0
jest to automatycznie prywatne, ponieważ jest zdefiniowane w zakresie innej metody.
override
adnotacja w Javie - kod działa bez niej, ale jeśli go tam umieścisz, powie ci, czy popełniłeś błąd.