اسامی مستعار و کلاس های inline در کاتلین — به زبان ساده

۱۰۶ بازدید
آخرین به‌روزرسانی: ۰۱ مهر ۱۴۰۲
زمان مطالعه: ۳ دقیقه
اسامی مستعار و کلاس های inline در کاتلین — به زبان ساده

کاتلین یک زبان برنامه‌نویسی مدرن است. در این نوشته به بررسی دو ویژگی جالب آن یعنی اسامی مستعار نوع و کلاس‌های inline در کاتلین می‌پردازیم. شکی نیست که کاتلین معرفی شده است تا مدت زیادی دوام داشته باشد و چنان که در کنفرانس I/O سال 2019 گوگل دیدیم، اعلام شد که کاتلین اینک به زبان ترجیحی گوگل برای توسعه اپلیکیشن‌های اندروید تبدیل شده است. در این کنفرانس گوگل اعلام کرد:

«امروز گامی بزرگ را اعلام می‌کنیم، توسعه اندروید اینک به حالت مبتنی بر کاتلین تبدیل شده است. بسیاری از API-ها و قابلیت‌های جت‌پک ابتدا در کاتلین عرضه می‌شوند. اگر یک پروژه جدید را آغاز می‌کنید، باید آن را در کاتلین بنویسید. کدی که به زبان کاتلین نوشته می‌شود به کدنویسی کمتری نیاز دارد و هر چه کد کمتری تایپ شود، تست و نگهداری کمتری هم نیاز خواهد داشت.»

اسامی مستعار

اسامی مستعار روش مناسبی برای تعیین نام های جایگزین برای انواع موجود محسوب می‌شوند.

همه ما با موقعیت‌هایی مواجه شده‌ایم که کلاس خاصی دارای نام طولانی یا پیچیده مانند MyAwesomeSupperDupperPowerClass بوده است. با بهره‌گیری از اسامی مستعار می‌توان یک نام متفاوت کوتاه‌تر یا معنی‌دارتر تعیین کرد و از این نام جدید به جای نام قبلی استفاده کرد.

سناریوی زیر را فرض کنید که یک جفت رشته حاوی نام کاربری و رمز عبور است:

1val myUserPass = Pair("myUsername1","myhashpassword1")

ما یک وهله از Pair ایجاد کردیم که به صورت یک نام کاربری و یک رمز عبور هش شده استفاده می‌شود. با این حال این وضعیت ساختار چندانی در اختیار ما قرار نمی‌دهد و چندان روشن نیست. شاید استفاده از چیزی مانند زیر بهتر باشد:

1typealias Credentials = Pair<String, String>
2
3val myCredentials = Credentials("myUsername1","myhashpassword1")
4

بدین ترتیب ساختار بهتری به دست می‌آوریم و خوانایی کد نیز افزایش می‌یابد. اسامی مستعار نوع‌های جدیدی را تعریف نمی‌کنند. آن‌ها معادل نوع‌های قبلی خود هستند.

مثال خوب دیگر جایی است که می‌توان از اسامی مستعار نوع در زمان نیاز به تعریف دو کلاس با نام یکسان اما پکیج‌های مختلف استفاده کرد. زمانی که این حالت پیش بیاید به طور معمول کلاس دوم را با استفاده از نام کلاس کامل مورد ارجاع قرار می‌دهیم. این موقعیت می‌تواند به صورت زیر نیز حل شود:

1typealias MyCustomView = com.filipebaptista.demoapp.customviews.View

اسامی مستعار نوع می‌توانند برای نامگذاری نوع تابع نیز استفاده شوند و همچنین از آن‌ها به همراه نام‌های پارامتر نوع تابع استفاده می‌شود:

1typealias ClickHandler = (View) -> Unit
2typealias OnElementClicked = (position: Int, view: View) -> Unit

کلاس‌های inline یا درون‌خطی

برخی اوقات برای منطق تجاری یا خوانایی کد لازم است که یک پوشش پیرامون نوع بسازیم، اما این کار به دلیل تخصیص‌های هیپ بیشتر، یک سربار زمان اجرا تولید می‌کند.

برای جلوگیری از این وضعیت در کاتلین نسخه 1.3 «کلاس‌های درون‌خطی» (Inline classes) معرفی شدند. این نوع خاص از کلاس‌ها موجب می‌شوند که این بهینه‌سازی صورت گیرد، زیرا داده‌ها در کاربردهایشان به صورت درون‌خطی تعریف می‌شوند و در واقع از وهله‌سازی شیء اجتناب می‌شود.

کلاس‌های درون‌خطی باید یک مشخصه منفرد داشته باشند که در سازنده اصلی مقداردهی می‌شود.

1inline class Age(val value:Int)

همان طور که قبلاً اشاره کردیم زمانی که از یک کلاس درون‌خطی استفاده می‌کنید در واقع هیچ مقداردهی در عمل اتفاق نمی‌افتد. در زمان اجرا وهله‌های کلاس درون‌خطی با استفاده از این مشخصه منفرد نمایش پیدا می‌کنند. به مثال زیر توجه کنید:

1inline class Age(val value:Int)
2inline class Height(val value:Int)
3data class User(val name: String, val age: Age, val height: Height)
4
5val ageUser1 = Age(36)
6val heightUser1 = Height(170)
7val user1 = User("Username1",ageUser1 ,heightUser1)

بدین ترتیب هیچ وهله‌سازی واقعی از کلاس‌های Age و Height صورت نمی‌گیرد و در زمان اجرا ageUser1 و height1 صرفاً شامل Int هستند.

کلاس‌های درون‌خطی مانند کلاس‌های معمولی می‌توانند مشخصه‌ها و تابع‌هایی داشته باشند و می‌توانند از اینترفیس‌ها ارث‌بری کنند، اما برخی محدودیت‌ها به صورت زیر نیز دارند:

  • بلوک‌های init مجاز نیستند.
  • مشخصه‌ها نمی‌توانند فیلدهای پشتیبان داشته باشند.
  • نمی‌توانند در سلسله‌مراتب کلاس مشارکت داشته باشند. این بدان معنی است که آن‌ها مجاز به بسط کلاس‌های دیگر نیستند و باید final باشند.

اینک شاید از خود بپرسید: آیا کلاس‌های درون‌خطی همان اسامی مستعار برای نوع نیستند؟

این دو مفهوم بسیار شبیه به هم به نظر می‌رسند، چون هر دوی آن‌ها یک نوع جدید را تعریف می‌کنند و هر دو به صورت نوع زیرین خود در زمان اجرا ظاهر می‌شوند. با این حال تفاوت‌هایی نیز دارند:

  • کلاس‌های درون‌خطی یک نوع واقعاً جدید را تعریف می‌کنند.
  • اسامی مستعار نوع تنها یک نام جایگزین (مستعار) برای یک نوع موجود هستند.

از آنجا که این موارد هنوز در حالت آزمایشی هستند، اندروید استودیو هنگام استفاده از آن‌ها برخی هشدارها را می‌دهد. این هشدارها می‌توانند با تعریف فلگ‌های خاص کامپایلر در فایل gradle غیرفعال شوند.

1compileKotlin {
2    kotlinOptions.freeCompilerArgs += ["-XXLanguage:+InlineClasses"]
3}

برای کسب اطلاعات بیشتر در مورد اسامی مستعار نوع و کلاس‌های درون‌خطی به مستندات کاتلین (+) و (+) مراجعه کنید.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای ۰ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
itnext
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *