De la publicación del blog " Llamadas de cola, @tailrec y trampolines ":
- En Scala 2.8, también podrá utilizar la nueva
@tailrec
anotació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 @tailrec
anotació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 = {
^
override
anotació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
def
en 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
length0
es automáticamente privado porque está definido en el alcance de otro método.fuente