پروژههای مشترک به خوبی با جاوا کار میکند.
کاتلین یک زبان برنامهنویسی عمومی، رایگان، متن باز] عملگرا است که در ابتدا برای ماشین مجازی جاوا و اندروید طراحی شده بود که ویژگی های برنامهنویسی شی گرا و تابعی (functional) را دارد. این زبان بر قابلیت همکاری، ایمنی، وضوح و پشتیبانی از ابزار تمرکز دارد. نسخههایی از کاتلین که JavaScript ES5.1 را هدف قرار میدهد و کد بومی (که از LLVM استفاده میکند) برای تعدادی از پردازندهها نیز در دست تولید است.
کاتلین در سال ۲۰۱۰ در JetBrains، شرکتی كه در پشت IntelliJ IDEA قرار دارد سرچشمه گرفته و از سال ۲۰۱۲ متن باز است. در حال حاضر تیم کاتلین بیش از ۹۰ عضو تمام وقت از JetBrains دارد و پروژه کاتلین در گیت هاب (GitHub) بیش از ۳۰۰ همکار دارد. JetBrains در بسیاری از محصولات خود از جمله پرچمدار آنها IntelliJ IDEA از کاتلین استفاده میکند.
کاتلین مختصرتر از زبان جاوا است
در نگاه اول کاتلین نسخه مختصر و سادهتر جاوا به نظر می رسد. برای مثال در تصویر بالا که در آن نمونه کد جاوا (در سمت چپ) را به صورت خودکار به کاتلین تبدیل شده است. توجه کنید که تکرار بیدلیل ذاتی در متغیرهای جاوا از بین رفته است. اصطلاح زیر در جاوا
StringBuilder sb = new StringBuilder();
در کاتلین میشود
val sb = StringBuilder()
میبینید که توابع با کلمه کلیدی Fun تعریف شده اند و هنگامی که کاراکتر خطهای موجود باشند، نقطه ویرگول اختیاری است. کلمه کلیدی val نشان از یک ویژگی تنها خواندنی یا متغیر محلی دارد. کلمه کلیدی var نیز یک ویژگی قابل تغییر یا متغیر محلی را اعلام میکند.
با این وجود Kotlin کاملا ماشینی است. کلمات کلیدی Val و var فقط در صورت امکان استنباط نوع داده، قابل استفاده هستند. به نظر میرسد استنباط نوع با هر نسخه از کاتلین بهبود مییابد.
به بیان تابع در بالای هر دو صفحه نگاهی بیندازید. نوع دستور بازگشتی (return) در جاوا پیش از نمونه اولیه (prototype) است اما در کاتلین به دنبال نمونه اولیه میآید و مانند زبان پاسکال با دونقطه مشخص میشود.
از این مثال کاملاً واضح نیست اما کاتلین نیاز جاوا را مبنی بر اینکه اعضای توابع عضو گروه هستند را برطرف کرده است. در Kotlin، ممکن است توابع در سطح بالای یک پرونده، به طور محلی در داخل توابع دیگر، به عنوان یک تابع عضو در داخل یک کلاس یا یک شی و به عنوان یک گسترش تابع اعلان شود. گسترش توابع پسوند قابلیت # C را برای گسترش یک کلاس با قابلیتهای جدید بدون نیاز به جانشین شدن یک کلاس یا استفاده از هر نوع الگوی طراحی مانند دکوراتور فراهم میکند.
برای طرفداران زبان برنامهنویسی گرووی، کاتلین سازندگان را پیاده سازی میکند. در حقیقت سازندگان Kotlin را میتوان از type checked بررسی کرد.Kotlin از خواص پشتیبانی میکند که می تواند برای اجرای خواص تنبل، خواص قابل مشاهده، خاصیت وتوآی و خصوصیات نقشهبرداری شده مورد استفاده قرار گیرد.
برنامه عملکردی مکانیسم های ناهمزمان موجود در زبانهای دیگر به عنوان کتابخانهای با استفادههایی از کاتلین اcoroutines.min در کاتلین قابل اجرا است. که شامل async
/await
از C # و ECMAScript، کانالها و انتخاب از Go ، و generators
/yield
از C # و فایتون است.
برنامه نویسی کاربردی در کاتلین
اجازه دادن به توابع سطح بالا، تنها آغاز داستان برنامه نویسی کاربردی برای این زبان است. همچنین این زبان از توابع مرتبه بالاتر، توابع ناشناس، لامبدا، توابع درون خطی، بسته شدن، الگوریتمهای بازگشتی و ژنریک پشتیبانی می کند. به عبارت دیگر Kotlin تمام ویژگیها و مزایای یک زبان کاربردی را دارد. به عنوان مثال اصطلاحات عملکردی زیر را در نظر بگیرید.
فیلتر کردن لیست در کاتلین
val positives = list.filter { x -> x > 0 }
برای توضیح سادهتر، وقتی تنها یک پارامتر واحد در عملگر لامبدا وجود دارد از it استفاده کنید.
val positives = list.filter { it > 0 }
حرکت نقشه/ لیست جفت ها در کاتلین
for ((k, v) in map) { println(“$k -> $v”) }
k و v را می توان هر چیزی نامید.
استفاده از محدوده ها در کاتلین
for (i in 1..100) { ... } // closed range: includes 100
for (i in 1 until 100) { ... } // half-open range: does not include 100
for (x in 2..10 step 2) { ... }
for (x in 10 downTo 1) { ... }
if (x in 1..10) { ... }
مثالهای بالا کلمه کلیدی FOR و همچنین استفاده از محدوده ها را نشان می دهد.
گرچه Kotlin زبان برنامه نویسی کاربردی کاملی است، اما اکثر ماهیت شی گرا بودن جاوا را به عنوان یک سبک برنامه نویسی جایگزین حفظ میکند که هنگام تبدیل کد جاوا موجود بسیار مفید است. کاتلین کلاسهایی با سازندگان دارد؛ کلاس های داخلی، تو در تو و کلاسهای تودرتوی ناشناس و رابطهایی مانند جاوا ۸. Kotlin کلمه کلیدی جدیدی ندارد. برای ایجاد نمونه کلاس، سازنده را درست مثل یک عملگر معمولی در نظر بگیرید. این را در تصویر بالا دیدیم.
کلاسهای کاتلین باید با کلمه کلیدی open
مشخص شوند تا سایر کلاسها بتوانند جایگرین آنها شوند. کلاسهای جاوا برعکس است زیرا آنها قابل اعتماد هستند مگر اینکه با کلمه کلیدی final
مشخص شود. کاتلین از یک ابر کلاس به نام وراث واحدی برخوردار است و کلیه کلاسهای کاتلین دارای یک ابرخودرو پیش فرض Any
هستند که با کلاس Java Java پایه java.lang.Objec
یکسان نیست. Any
فقط شامل سه عملکرد عضو از پیش تعریف شده است: مساوی () ، hashCode () و toString ().
کلاسهای Kotlin باید با کلمه کلیدی open
علامتگذاری شوند تا کلاس های دیگر بتوانند جایگزین آنها شوند؛ کلاسهای جاوا برعکس است، زیرا آنها قابل انتقال هستند مگر اینکه با کلمه کلیدی final
مشخص شده باشند. برای رد کردن یک روش سوپرکلاس، خود روش باید open
شده و به صورتoverride
علامتگذاری شود. فلسفه زبان کاتلین در روشن ساختن امور به جای تکیه بر پیش فرضها حائز اهمیت است. مشخص است که در این مورد خاص روش كاتلین چندین خطای معمول جاوا را پوشش میدهد.
ویژگی های ایمنی در زبان کاتلین
کاتلین برای از بین بردن خطر ارجاعات به اشارهگرهای تهی (null) و ساده کردن کار با مقادیر null طراحی شده است. در این زبان استفاده ازnull
برای نوع های استاندارد، افزودن انواع nullable و اجرای نمادهای میانبر برای انجام تست های null غیرقانونی است.
مثلا یک متغیر معمولی از نوع String نمی تواند null باشد:
var a: String = "abc"
a = null // compilation error
به عنوان مثال اگر برای نگه داشتن نتایج جستجوی SQL، باید null ها را مجاز بدانید، می توانید با افزودن یک علامت سؤال به نوع، مثلاً یک نوع را nullable اعلام کنید. مثلا ?String.
var b: String? ="abc"
b = null // ok
حفاظتها کمی بیشتر میشود. میتوانید از یک نوع non-nullabl استفاده کنید اما باید قبل از استفاده از آن یک نوع nullable را برای مقادیر null تست کنید.
برای اجتناب از دستور زبان شفاهی که معمولاً برای آزمایش null لازم است، کاتلین از عملگر فراخوانی ایمن (safe call) علامت سوال را معرفی می کند. برای مثال b?.length
می شود b.length
اگر b تهی(null) نباشد. نوع این عبارت می شود ?Int.
به عبارت دیگرb?.length
یک میانبر است برای اینکه (b != null)
و به جز آنnull
است. این هماهنگی منطق متن طولانی را از بین میبرد، به خصوص هنگامی که یک شی از یک سری پرسشهای پایگاه داده جمع شده که هر یک از آنها ممکن است بیفایده باشد. برای مثال bob?.department?.head?.name
دستور بازگشتی اسم رئیس بخش باب است اگر باب، بخش و رئیس بخش همگی non-null باشند.
برای انجام یک عملیات خاص فقط برای مقادیر non-null، میتوانید از اپراتور فراخوانی ایمن .?
همراه با let
استفاده کنید:
val listWithNulls: List<String?> = listOf("A", null)
for (item in listWithNulls) {
item?.let { println(it) } // prints A and ignores null }
غالباً میخواهید یک مقدار صحیح اما خاص از یک عبارت nullable را به گونهای که بتوانید آن را در نوع non-nullable ذخیره کنید، بازگردانید. یک دستور ویژه برای این کار وجود دارد که به آن اپراتور الویس (Elvis) میگویند و به صورت :?
نوشته میشود.
val l = b?.length ?: -1
و معادل این است:
val l: Int = if (b != null) b.length else -1
در همین راستا، Kotlin استثناهای بررسی شده جاوا که شرطهای throwable هستند را حذف میکند. مثلا امضای JDK
Appendable append(CharSequence csq) throws IOException;
شما را ملزم می کند که با هر بار فراخوانی با متد append
یک IOException
بگیرید:
try {
log.append(message)
}
catch (IOException e) {
// Do something with the exception
}
طراحان جاوا فکر میکردند که این یک ایده خوب و یک پیروزی برای برنامههای آموزشی است تا زمانی که برنامه نویسان چیزی معقول در شرط catch
را اجرا کنند. با این وجود اغلب در برنامههای بزرگ جاوا، کدی را میبینید که شرط catch
اجباری چیزی جز یک کامنت را ندارد://todo: handle this.
این کار کمکی نمیکند و مشخص شد که استثنائات بررسی شده ضرری خالص برای برنامههای بزرگ است.
ویژگی های همروال کاتلین
همروالها (Coroutines) در Kotlin در اصل نخهایی کم حجم (lightweight threads) هستند. آنها را با launch
سازنده همروال در زمینه چند از CoroutineScope
شروع میکنید. یكی از مفیدترین اسكاترهای همروال، {}runBlocking
است که در مورد دامنه code block آن قابل اجراست.
import kotlinx.coroutines.*
fun main() = runBlocking { // this: CoroutineScope
launch { // launch a new coroutine in the scope of runBlocking
delay(1000L) // non-blocking delay for 1 second
println("World!")
}
println("Hello,")
}
این کد با یک تأخیر یک ثانیهای بین خطوط، خروجی زیر را تولید می کند:
سلام.
دنیا!
کاتلین برای اندروید
تا مه ۲۰۱۷، تنها زبانهای برنامه نویسی Java و C ++ به طور رسمی از اندروید پشتیبانی میکردند. در سال ۲۰۱۷ کمپانی گوگل در Google I/O پشتیبانی رسمی از کاتلین در اندروید را اعلام کرد و با شروع Android Studio 3.0، کاتلین در مجموعه ابزارهای توسعه اندروید قرار دارد. میتوان با یک پلاگین کاتلین را به نسخههای قبلی Android Studio اضافه کرد.
کاتلین با همان بایت کد جاوا کامپایل شده و به روشهای معمول با کلاسهای جاوا همکاری کرده و ابزار خود را با جاوا به اشتراک میگذارد. از آنجا که هیچ گونه ابهامی برای کال بک بین Kotlin و Java وجود ندارد، اضافه کردن تدریجی Kotlin به یک برنامه اندرویدی که در حال حاضر در جاوا وجود دارد، معنی پیدا میکند. معدود مواردی مانند ویژگیهای تنظیم شده جاوا، که در آن قابلیت همکاری بین Kotlin و کد جاوا فاقد اعتبار است به ندرت دیده شده و به راحتی برطرف میشود.
پینترست (Pinteres) فرزند پوستر برای برنامههای اندرویدی است که در اوایل نوامبر ۲۰۱۶ در کاتلین نوشته شده و به طور مشخص در Google I/O سال ۲۰۱۷ به عنوان بخشی از اعلامیه کاتلین ذکر شده است. علاوه بر این تیم Kotlin به برنامههای Evernote ،Trello ،Square و Coursera را برای اندروید استناد کند.
کاتلین و جاوا
این سوال که آیا باید کاتلین یا جاوا را برای توسعه جدید انتخاب کنیم، از زمان اعلام Google I/O در جامعه اندروید بسیار زیاد شده است؛ اگرچه مردم پیش از این در فوریه ۲۰۱۶ هنگام Kotlin 1.0 این سؤال را مطرح میکردند. پاسخ این است که کد Kotlin امن تر و مختصر تر از کد جاوا است و این که فایلهای Kotlin و Java می توانند در برنامههای اندرویدی با هم وجود داشته باشند به طوری که Kotlin نه تنها برای برنامههای جدید بلکه برای گسترش برنامههای موجود جاوا نیز مفید است.
تنها استدلالی که در مورد انتخاب جاوا در برابر کاتلین دیده می شود این است که در مورد موارد جدید توسعه اندروید است. اینکه از لحاظ تاریخی بیشتر اسناد و نمونههای اندرویدی در جاوا هستند، ممکن است مانعی برای غلبه بر آن باشد. از سوی دیگر تبدیل جاوا به کاتلین در اندروید استودیو یک مسئله ساده برای قرار دادن کد جاوا در یک فایل کاتلین است.
مزایای Kotlin تقریباً برای هر کسی که توسعه اندروید را انجام میدهد، قانع کننده است. زمان نقل شده یادگیری کاتلین برای توسعه دهندگان جاوا چند ساعت است: هزینهای کم برای پرداخت خطاهای مرجع null، فعال کردن توابع فرمت، پشتیبانی از برنامه نویسی کاربردی و اضافه کردن همروال ها. در تخمین معمولی، تعداد خطوط کد از جاوا به Kotlin کاهش ۴۰ درصدی را نشان میدهد.
کاتلین و اسکالا
این سؤال که بین کاتلین و اسکالا کدام یک را انتخاب کنید در جامعه اندروید به وجود نمیآید؛ زیرا پشتیبانی اسکالا از ابزار اندروید خیلی خوب نیست و کتابخانه اسکالا برای اندروید تمایل زیادی به آن دارد. از سوی دیگر جامعه اسکالا کاملا از این مسائل آگاه بوده و روی راهکارهای آن کار میکند.
شرایط در سایر محیطها متفاوت است. به عنوان مثال، Apache Spark بیشتر در اسکالا نوشته شده است و برنامههای بزرگ داده برای Spark اغلب در اسکالا نوشته میشوند.
از جهات مختلف هم اسکالا و هم کاتلین نشاندهنده تلفیق برنامه نویسی شی گرا هستند، همانطور که جاوا در برنامه نویسی کاربردی مثال زدنی است. این دو زبان مفاهیم و نمادهای مشابه زیادی با یکدیگر دارند مانند اعلامیه های تغییرناپذیر با استفاده از val
و قابل تغییر با استفاده از var
؛ اما در مورد سایرین کمی متفاوت است مانند اینکه در هنگام اعلام عملگر lambda فلش را چگونه بگذارید و اینکه از یک پیکان (arrow) تک یا دوبل استفاده کنید. data class
کاتلین مانند case class
اسکالا است.
کاتلین متغیرهای تعی پذیر را به روشی شبیه به#Groovy ،C # و F # باشد؛ اکثر مردم آن را سریع میفهمند. از طرف دیگر اسکالا متغیرهای nullable را با استفاده از Option
تک تعریف میکند که آنقدر عجیب است تا برخی از نویسندگان فکر کنند اسکالا از امنیت null برخوردار نیست.
یکی از کمبودهای واضح اسکالا طولانی بودن زمان کامپایل آن است. از طرف دیگر کاتلین برای کامپایل سریع در اغلب سناریوهای توسعه نرم افزار طراحی شده و در واقع سریعتر از کد جاوا کامپایل میشود.
قابلیت همکاری کاتلین با جاوا
با توجه به تفاوت در رسیدگی به null
و استثنائات بررسی شده، اینکه Kotlin چگونه نتایج فراخوان قابلیت همکاری با جاوا را کنترل میکند جالب توجه است. این زبان با سکوت و قابل اطمینان آنچه را که “نوع پلتفرم” نامیده می شود را استنتاج می کند و دقیقاً مانند یک نوع جاوا رفتار میکند: یعنی چیزی که nullable است اما استثنائی برای null-pointer ایجاد می کند. در زمان کامپایل به کد، تاکیدی (assertion) میکند تا از تحریک یک استثنای null pointer واقعی جلوگیری کند. هیچ نشانه گذاری صریح برای یک نوع پلتفرم وجود ندارد، اما در صورتی که کاتلین مجبور شود نوع پلتفرم را گزارش دهد، !
را به نوع اضافه میکند.
در بیشتر موارد فراخوان کدهای جاوا از کاتلین به روشی که انتظار دارید انجام میشود. به عنوان مثال در یک کلاس جاوا، هر زمان که گیرنده و تنظیم کننده وجود داشته باشند، کاتلین از آنها با عنوان ویژگیهایی با همین نام رفتار میکند. به همین ترتیب روشهای دسترسی Boolean به عنوان خصوصیاتی شناخته میشوند که نام مشابهی با روش گیرنده دارند. به عنوان مثال:
import java.util.Calendar
fun calendarDemo() {
val calendar = Calendar.getInstance()
if (calendar.firstDayOfWeek == Calendar.SUNDAY) { // call getFirstDayOfWeek()
calendar.firstDayOfWeek = Calendar.MONDAY // call setFirstDayOfWeek()
}
if (!calendar.isLenient) { // call isLenient()
calendar.isLenient = true // call setLenient()
}
}
این طرح در ویژگیهای تنظیم شده جاوا که هنوز در کاتلین پشتیبانی نمیشوند، اثری ندارد. اگر یک کلاس جاوا تنها یک تنظیم کننده داشته باشد، به عنوان یک ویژگی در کاتلین قابل مشاهده نیست.
قابلیت همکاری Kotlin با جاوا به ابزارهای جاوا نیز می رسد. کاتلین ادیتور یا IDE خود را ندارد؛ این پلاگین ها برای ادیتورها و IDE های معروف جاوا از جمله IntelliJ IDEA، اندروید استودیو و Eclipse است. کاتلین سیستم ساخت خاص خود را ندارد و از Ant، گریدل (Gradle) و ماون (Maven) استفاده میکند.
قابلیت همکاری کاتلین و جاوا اسکریپت
می توانید از Kotlin برای نوشتن کد برای مرورگرها و Node.js استفاده کنید. اینگونه این زبان به جای اینکه در بایت کد JVM کامپایل شود به JavaScript ES5.1 ترنسپایل میشود.
از آنجا که جاوا اسکریپت یک زبان پویا است، کاتلین یک نوع پویا را که در کاتلین برای JVM در دسترس نیست، به آن اضافه میکند:
val dyn: dynamic = ...
بررسی کننده نوع (type checker) در کاتلین نوع dynamic
را نادیده می گیرد و به جاوا اسکریپت اجازه میدهد تا در زمان اجرا با آنها سر و کار داشته باشد. عباراتی که از مقادیر از نوع dynamic
استفاده میکنند، همانطور که نوشته شدهاند به جاوا اسکریپت ترجمه میشوند. در اینجا مجددا كاتلین جاوا اسکریپت اجازه میدهد تا عبارات را در زمان اجرا تفسیر كند.
به دو روش میتوانید جاوا اسکریپت را در Kotlin فراخوانی کنید: با استفاده از انواع dynamic
یا استفاده از نوع دهی نیرومند (strongly typed) برای کتابخانههای جاوا اسکریپت. برای دسترسی به چارچوبهای شخص ثالث معروف جاوا اسکریپت با یک API نوع دهی نیرومند، می توانید با استفاده از ابزار ts2kt، تعاریف TypeScript را از مخازن تعاریف نوع DefinitelyTyped به کاتلین تبدیل کنید.
با استفاده از عملگر js("…")
میتوانید کد جاوا اسکریپت را به عنوان متن درون کد Kotlin خود وارد کنید. می٬توانید با استفاده از اصلاح کننده external
اظهارات بسته شده خود را در کد کاتلین به عنوان جاوا اسکریپت علامت گذاری کرده و با استفاده از کد کاتلین از جاوا اسکریپت فراخوانی کنید، اما باید از نامهای مشروط استفاده کنید.
برنامه های کاتلین
از Kotlin هر نوع توسعه استفاده میشود: سمت سرور، وب سمت کلاینت، اندروید و کد بومی. یک نظرسنجی که کمی پس از انتشار Kotlin / Native انجام شد، نشان داد که ۶۶ درصد از توسعه دهندگانی که کاتلین را در بین سه زبان برتر برنامه نویسی خود قرار دادند، از آن برای اندروید، ۵۷ درصد برای ماشین مجازی جاوا، ۸ درصد برای Kotlin/Native و ۵ درصد برای جاوا اسکریپت استفاده میکردند.
توسعه دهندگان Kotlin / Native میگویند که آنها (به ترتیب تناوب) لینوکس، اندروید، macOS، ویندوز، iOS WebAssemble و سیستمهای جاسازی شده را هدف قرار داده اند.
به طور کلی، کاتلین نسبت به جاوا چندین مزیت نسبت برای اجرای کد در JVM ارائه می دهد و همچنین برای تولید کدهای جاوا اسکریپت و بومی مورد استفاده قرار میگیرد. این زبان در مقایسه با جاوا ایمنتر، مختصرتر و صریحتر است. این زبان از برنامه نویسی کاربردی علاوه بر برنامه نویسی شی گرا پشتیبانی کرده، مجموعهای از ویژگی های مفید (گسترش توابع، سازندهها، همروالها، lambdas و غیره) را ارائه میدهد و از طریق انواع nullable و non-nullable، ایمنی null را فراهم میکند. مهمتر از همه اینکه اگر جاوا را از قبل میشناسید، بدون صرف زمان در kotlin به بازهی میرسید.
منبع: