امکانات بسیار زیادی در Kotlin قرار گرفته تا بتواند به زبان رسمی Android مبدل گردد. tailrec یکی از آنهاست. این امکان در توابع بازگشتی کاربرد دارد. همانطور که می دانید استفاده از توابع بازگشتی معمولاً روشی نا صحصیح است که با مقیم شدن در حافظه تا تمام شدن تمامی مراحل، می تواند باعث stack overflow گردد و در طراحی الگوریتم روشی brutal است. این امکان وجود دارد تا توابع برگشتی را با استفاده از حلقه بهینه کرد.
با گذاشتن tailrec در اول تابع بازگشتی، kotlin خودش آن را هنگام کامپایل کردن در صورت برقرار بودن شرایط، پیاده سازی آن تابع را با حلقه انجام داده و کد را بهینه می کند. به عنوان نمونه به تابع فاکتوریل زیر توجه کنید:
1 2 3 4 5 6 7 8 9 |
fun fact(x: Long): Long { tailrec fun factTail(y: Long, z: Long): Long { return if (y == 0L) z else { return factTail(y - 1, y * z) } } return factTail(x, 1) } |
برای صدا زدن کافیست:
1 |
logg("$5! : ${fact(5)}") |
استفاده از tailrec شرایط دارد از قبیل اینکه بعد از صدا زدن recursive نباید متد دیگری وجود داشته باشد و یا مثلا اینکه درون بلاک های try/catch/finally نمی توان استفاده کرد. مثال کامل Kotlin را می توانید در لینک ذیل مشاهده کنید.