De la publicación del blog " Llamadas de cola, @tailrec y trampolines ":
- En Scala 2.8, también podrá utilizar la nueva
@tailrecanotación para obtener información sobre qué métodos están optimizados.
Esta anotación le permite marcar métodos específicos que espera que el compilador optimice.
A continuación, recibirá una advertencia si el compilador no los optimiza.
- En Scala 2.7 o versiones anteriores, deberá confiar en las pruebas manuales o en la inspección del código de bytes para determinar si un método se ha optimizado.
Ejemplo:
puede agregar una @tailrecanotación para estar seguro de que los cambios han funcionado.
import scala.annotation.tailrec
class Factorial2 {
def factorial(n: Int): Int = {
@tailrec def factorialAcc(acc: Int, n: Int): Int = {
if (n <= 1) acc
else factorialAcc(n * acc, n - 1)
}
factorialAcc(1, n)
}
}
Y funciona desde el REPL (ejemplo de los consejos y trucos de Scala REPL ):
C:\Prog\Scala\tests>scala
Welcome to Scala version 2.8.0.RC5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_18).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import scala.annotation.tailrec
import scala.annotation.tailrec
scala> class Tails {
| @tailrec def boom(x: Int): Int = {
| if (x == 0) throw new Exception("boom!")
| else boom(x-1)+ 1
| }
| @tailrec def bang(x: Int): Int = {
| if (x == 0) throw new Exception("bang!")
| else bang(x-1)
| }
| }
<console>:9: error: could not optimize @tailrec annotated method: it contains a recursive call not in tail position
@tailrec def boom(x: Int): Int = {
^
<console>:13: error: could not optimize @tailrec annotated method: it is neither private nor final so can be overridden
@tailrec def bang(x: Int): Int = {
^
overrideanotación en Java: el código funciona sin él, pero si lo pones allí te dice si cometiste un error.La anotación es
scala.annotation.tailrec. Desencadena un error del compilador si el método no se puede optimizar para la llamada final, lo que sucede si:Se coloca justo antes de
defen una definición de método. Funciona en REPL.Aquí importamos la anotación e intentamos marcar un método como
@tailrec.¡Ups! ¡La última invocación es
1.+(), nolength()! Reformulemos el método:Tenga en cuenta que
length0es automáticamente privado porque está definido en el alcance de otro método.fuente