L'annotation est scala.annotation.tailrec
. Il déclenche une erreur du compilateur si la méthode ne peut pas être optimisée pour l'appel de fin, ce qui se produit si:
- L'appel récursif n'est pas en position de queue
- La méthode pourrait être remplacée
- La méthode n'est pas définitive (cas particulier de la précédente)
Il est placé juste avant le def
dans une définition de méthode. Cela fonctionne dans le REPL.
Ici, nous importons l'annotation et essayons de marquer une méthode comme @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 {
^
Oups! La dernière invocation est 1.+()
, non length()
! Reformulons la méthode:
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
Notez que length0
c'est automatiquement privé car il est défini dans le cadre d'une autre méthode.
override
annotation en Java - le code fonctionne sans elle, mais si vous la mettez là, elle vous indique si vous avez fait une erreur.