Аннотация есть scala.annotation.tailrec
. Он вызывает ошибку компилятора, если метод не может быть оптимизирован для хвостового вызова, что происходит, если:
- Рекурсивный вызов не в хвостовой позиции
- Метод может быть переопределен
- Метод не окончательный (частный случай предыдущего)
Он помещается непосредственно перед def
в определении метода. Работает в REPL.
Здесь мы импортируем аннотацию и пытаемся пометить метод как @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 {
^
Ой! Последний призыв - 1.+()
нет length()
! Переформулируем метод:
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
Обратите внимание, что length0
это автоматически закрытый, потому что он определен в области действия другого метода.
override
аннотации в Java - код работает и без нее, но если вы поместите его туда, он сообщит вам, если вы сделали ошибку.