Dari entri blog " Panggilan ekor, @tailrec, dan trampolin ":
- Di Scala 2.8, Anda juga dapat menggunakan
@tailrec
anotasi baru untuk mendapatkan informasi tentang metode mana yang dioptimalkan.
Anotasi ini memungkinkan Anda menandai metode tertentu yang Anda harap akan dioptimalkan oleh compiler.
Anda kemudian akan mendapatkan peringatan jika tidak dioptimalkan oleh kompiler.
- Di Scala 2.7 atau sebelumnya, Anda perlu mengandalkan pengujian manual, atau pemeriksaan bytecode, untuk mengetahui apakah suatu metode telah dioptimalkan.
Contoh:
Anda dapat menambahkan @tailrec
anotasi sehingga Anda dapat yakin bahwa perubahan Anda telah berhasil.
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)
}
}
Dan itu bekerja dari REPL (contoh dari tip dan trik 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
anotasi di Java - kodenya bekerja tanpa itu, tetapi jika Anda meletakkannya di sana, ia memberi tahu Anda jika Anda membuat kesalahan.Anotasinya adalah
scala.annotation.tailrec
. Ini memicu kesalahan kompiler jika metode tidak dapat dioptimalkan panggilan ekor, yang terjadi jika:Ini ditempatkan tepat sebelum
def
definisi metode. Ia bekerja di REPL.Di sini kami mengimpor anotasi, dan mencoba menandai metode sebagai
@tailrec
.Ups! Doa terakhir adalah
1.+()
, bukanlength()
! Mari kita rumuskan kembali metodenya:Perhatikan bahwa
length0
secara otomatis bersifat pribadi karena ditentukan dalam cakupan metode lain.sumber