این کد لبه بخشی از دوره Kotlin Bootcamp برای برنامه نویسان است. اگر به ترتیب روی کدها کار کنید، بیشترین ارزش را از این دوره خواهید گرفت. بسته به دانش خود، ممکن است بتوانید برخی از بخش ها را مرور کنید. این دوره مختص برنامه نویسانی است که یک زبان شی گرا را می دانند و می خواهند Kotlin را یاد بگیرند.
مقدمه
در این کد لبه شما با کلاس ها، توابع و متدهای عمومی و نحوه کار آنها در Kotlin آشنا می شوید.
به جای ساختن یک برنامه نمونه واحد، درسهای این دوره برای ایجاد دانش شما طراحی شدهاند، اما نیمه مستقل از یکدیگر باشند تا بتوانید بخشهایی را که با آنها آشنا هستید، مرور کنید. برای گره زدن آنها به یکدیگر، بسیاری از نمونه ها از تم آکواریوم استفاده می کنند. و اگر می خواهید داستان کامل آکواریوم را ببینید، دوره Kotlin Bootcamp for Programmers Udacity را بررسی کنید.
آنچه از قبل باید بدانید
- نحو توابع، کلاس ها و متدهای کاتلین
- نحوه ایجاد یک کلاس جدید در IntelliJ IDEA و اجرای یک برنامه
چیزی که یاد خواهید گرفت
- نحوه کار با کلاس ها، متدها و توابع عمومی
کاری که خواهی کرد
- یک کلاس عمومی ایجاد کنید و محدودیت ها را اضافه کنید
- انواع
inوoutایجاد کنید - توابع، متدها و توابع الحاقی عمومی ایجاد کنید
مقدمه ای بر ژنریک
کاتلین مانند بسیاری از زبان های برنامه نویسی دارای انواع عمومی است. یک نوع عمومی به شما امکان می دهد یک کلاس را عمومی کنید و در نتیجه یک کلاس را بسیار انعطاف پذیرتر کنید.
تصور کنید در حال پیاده سازی یک کلاس MyList هستید که لیستی از آیتم ها را در خود جای داده است. بدون ژنریک، شما باید یک نسخه جدید از MyList را برای هر نوع پیاده سازی کنید: یکی برای Double ، یکی برای String ، یکی برای Fish . با ژنریک، می توانید لیست را عمومی کنید، بنابراین می توانید هر نوع شی را در خود جای دهید. مانند این است که تایپ را به صورت عام درآورید که برای انواع مختلف مناسب باشد.
برای تعریف یک نوع عمومی، T را در پرانتزهای زاویه <T> بعد از نام کلاس قرار دهید. (می توانید از حرف دیگری یا نام طولانی تر استفاده کنید، اما قرارداد یک نوع عمومی T است.)
class MyList<T> {
fun get(pos: Int): T {
TODO("implement")
}
fun addItem(item: T) {}
} شما می توانید T به عنوان یک نوع معمولی ارجاع دهید. نوع برگشتی get() T است و پارامتر addItem() از نوع T است. البته لیست های عمومی بسیار مفید هستند، بنابراین کلاس List در Kotlin تعبیه شده است.
مرحله 1: یک سلسله مراتب نوع ایجاد کنید
در این مرحله چند کلاس ایجاد می کنید تا در مرحله بعد از آنها استفاده کنید. طبقه بندی فرعی در یک کد آزمایشگاهی قبلی پوشش داده شده بود، اما در اینجا یک بررسی مختصر وجود دارد.
- برای بی نظم نگه داشتن مثال، یک بسته جدید در زیر src ایجاد کنید و آن را
genericsنامید. - در بسته ژنریک ، یک فایل
Aquarium.ktجدید ایجاد کنید. این به شما امکان میدهد تا چیزها را با استفاده از نامهای یکسان بدون تداخل تعریف کنید، بنابراین بقیه کد شما برای این کد لبه به این فایل میرود. - سلسله مراتبی از انواع تامین آب ایجاد کنید. با تبدیل کردن
WaterSupplyبه یک کلاسopenشروع کنید تا بتوان آن را زیرکلاس بندی کرد. - یک پارامتر
varboolean اضافه کنید،needsProcessing. این به طور خودکار یک ویژگی قابل تغییر به همراه یک گیرنده و تنظیم کننده ایجاد می کند. - یک زیرکلاس
TapWaterبسازید کهWaterSupplyگسترش می دهد و برایneedsProcessingآن راtrueبنویسید، زیرا آب لوله کشی حاوی مواد افزودنی است که برای ماهی مضر است. - در
TapWater، تابعی به نامaddChemicalCleaners()تعریف کنید که پس از تمیز کردن آب،needsProcessingرویfalseقرار می دهد. ویژگیneedsProcessingمی توان ازTapWaterتنظیم کرد، زیرا به طور پیش فرضpublicاست و برای زیر کلاس ها قابل دسترسی است. در اینجا کد تکمیل شده است.
package generics
open class WaterSupply(var needsProcessing: Boolean)
class TapWater : WaterSupply(true) {
fun addChemicalCleaners() {
needsProcessing = false
}
}- دو زیر کلاس دیگر از
WaterSupplyبه نام هایFishStoreWaterوLakeWaterایجاد کنید.FishStoreWaterنیازی به پردازش ندارد، اماLakeWaterباید با روشfilter()فیلتر شود. پس از فیلتر کردن، نیازی به پردازش مجدد نیست، بنابراین درfilter()needsProcessing = falseتنظیم کنید.
class FishStoreWater : WaterSupply(false)
class LakeWater : WaterSupply(true) {
fun filter() {
needsProcessing = false
}
}اگر به اطلاعات بیشتری نیاز دارید، درس قبلی در مورد وراثت در کاتلین را مرور کنید.
مرحله 2: یک کلاس عمومی بسازید
در این مرحله کلاس Aquarium را برای پشتیبانی از انواع مختلف منابع آب تغییر می دهید.
- در Aquarium.kt ، یک کلاس
Aquariumرا با<T>در پرانتز بعد از نام کلاس تعریف کنید. - اضافه کردن یک ویژگی تغییر ناپذیر
waterSupplyاز نوعTبهAquarium.
class Aquarium<T>(val waterSupply: T)- تابعی به نام
genericsExample()بنویسید. این بخشی از یک کلاس نیست، بنابراین می تواند در سطح بالای فایل مانند تابعmain()یا تعاریف کلاس قرار گیرد. در عملکرد، یکAquariumبسازید و آن را بهWaterSupplyارسال کنید. از آنجایی که پارامترwaterSupplyعمومی است، باید نوع آن را در براکت های زاویه<>مشخص کنید.
fun genericsExample() {
val aquarium = Aquarium<TapWater>(TapWater())
}- در
genericsExample()کد شما می تواند بهwaterSupplyآکواریوم دسترسی داشته باشد. از آنجایی که از نوعTapWaterاست، می توانیدaddChemicalCleaners()بدون هیچ نوع cast فراخوانی کنید.
fun genericsExample() {
val aquarium = Aquarium<TapWater>(TapWater())
aquarium.waterSupply.addChemicalCleaners()
}- هنگام ایجاد شی
Aquarium، میتوانید براکتهای زاویه و آنچه را که بین آنها وجود دارد حذف کنید، زیرا کاتلین استنتاج نوع دارد. بنابراین دلیلی وجود ندارد که هنگام ایجاد نمونه، دو بار بگوییدTapWater. نوع را می توان با استدلال بهAquariumاستنباط کرد. همچنان یکAquariumاز نوعTapWaterخواهد ساخت.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
aquarium.waterSupply.addChemicalCleaners()
}- برای دیدن اینکه چه اتفاقی می افتد، قبل و بعد از فراخوانی
addChemicalCleaners()needsProcessingچاپ کنید. در زیر تابع کامل شده است.
fun genericsExample() {
val aquarium = Aquarium<TapWater>(TapWater())
println("water needs processing: ${aquarium.waterSupply.needsProcessing}")
aquarium.waterSupply.addChemicalCleaners()
println("water needs processing: ${aquarium.waterSupply.needsProcessing}")
}- یک تابع
main()برای فراخوانیgenericsExample()اضافه کنید، سپس برنامه خود را اجرا کنید و نتیجه را مشاهده کنید.
fun main() {
genericsExample()
}⇒ water needs processing: true water needs processing: false
مرحله 3: آن را مشخص تر کنید
عمومی به این معنی است که شما می توانید تقریباً هر چیزی را پاس کنید، و گاهی اوقات این یک مشکل است. در این مرحله کلاس Aquarium را در مورد آنچه که می توانید در آن قرار دهید مشخص تر می کنید.
- در
genericsExample()یکAquariumایجاد کنید و یک رشته برایwaterSupplyارسال کنید، سپس ویژگیwaterSupplyآکواریوم را چاپ کنید.
fun genericsExample() {
val aquarium2 = Aquarium("string")
println(aquarium2.waterSupply)
}- برنامه خود را اجرا کنید و نتیجه را مشاهده کنید.
⇒ string
نتیجه رشتهای است که پاس دادهاید، زیرا Aquarium هیچ محدودیتی برای T. ایجاد نمیکند. هر نوع، از جمله String ، میتواند به آن منتقل شود.
- در
genericsExample()یکAquariumدیگر ایجاد کنید که برایwaterSupplynullمیدهد. اگرwaterSupplynull است،"waterSupply is null"را چاپ کنید.
fun genericsExample() {
val aquarium3 = Aquarium(null)
if (aquarium3.waterSupply == null) {
println("waterSupply is null")
}
}- برنامه خود را اجرا کنید و نتیجه را مشاهده کنید.
⇒ waterSupply is null
چرا هنگام ایجاد یک Aquarium می توانید آن را null کنید؟ این امکان پذیر است زیرا به طور پیش فرض T مخفف nullable Any? نوع، نوع در بالای سلسله مراتب نوع. موارد زیر معادل همان چیزی است که قبلاً تایپ کردید.
class Aquarium<T: Any?>(val waterSupply: T)- برای اینکه اجازه ندهید
nullTAny، با حذف?بعد ازAny.
class Aquarium<T: Any>(val waterSupply: T)در این زمینه، Any یک محدودیت عمومی نامیده می شود. این بدان معنی است که هر نوع تا زمانی که null نباشد می تواند برای T ارسال شود.
- آنچه شما واقعاً می خواهید این است که مطمئن شوید فقط یک
WaterSupply(یا یکی از زیر کلاس های آن) می تواند برایTارسال شود. برای تعریف یک محدودیت عمومی خاص تر،AnyباWaterSupplyجایگزین کنید.
class Aquarium<T: WaterSupply>(val waterSupply: T)مرحله 4: بررسی بیشتر را اضافه کنید
در این مرحله با تابع check() آشنا می شوید تا مطمئن شوید کد شما مطابق انتظار عمل می کند. تابع check() یک تابع کتابخانه استاندارد در Kotlin است. این به عنوان یک ادعا عمل می کند و اگر آرگومان آن false ارزیابی شود، یک IllegalStateException ایجاد می کند.
- یک متد
addWater()را به کلاسAquariumاضافه کنید تا آب اضافه کنید، با یکcheck()که مطمئن می شود نیازی به پردازش آب ندارید.
class Aquarium<T: WaterSupply>(val waterSupply: T) {
fun addWater() {
check(!waterSupply.needsProcessing) { "water supply needs processing first" }
println("adding water from $waterSupply")
}
}در این مورد، اگر needsProcessing درست باشد، check() یک استثنا ایجاد می کند.
- در
genericsExample()کدی را برای ساختنAquariumباLakeWaterاضافه کنید و سپس مقداری آب به آن اضافه کنید.
fun genericsExample() {
val aquarium4 = Aquarium(LakeWater())
aquarium4.addWater()
}- برنامه خود را اجرا کنید، یک استثنا خواهید داشت، زیرا ابتدا آب باید فیلتر شود.
⇒ Exception in thread "main" java.lang.IllegalStateException: water supply needs processing first
at Aquarium.generics.Aquarium.addWater(Aquarium.kt:21)- قبل از افزودن آب به
Aquariumیک تماس برای فیلتر کردن آب اضافه کنید. اکنون وقتی برنامه خود را اجرا می کنید، هیچ استثنایی وجود ندارد.
fun genericsExample() {
val aquarium4 = Aquarium(LakeWater())
aquarium4.waterSupply.filter()
aquarium4.addWater()
}⇒ adding water from generics.LakeWater@880ec60
موارد فوق اصول اولیه ژنریک را پوشش می دهد. وظایف زیر موارد بیشتری را پوشش می دهند، اما مفهوم مهم این است که چگونه یک کلاس عمومی را با یک محدودیت عمومی اعلام و استفاده کنید.
در این کار، انواع درون و بیرون با ژنریک ها را یاد می گیرید. نوع in نوعی است که فقط می تواند به یک کلاس منتقل شود، اما برگردانده نمی شود. نوع out نوعی است که فقط از یک کلاس قابل بازگشت است.
به کلاس Aquarium نگاه کنید و خواهید دید که نوع عمومی آن تنها با دریافت waterSupply ملک بازگردانده می شود. هیچ روشی وجود ندارد که مقداری از نوع T را به عنوان پارامتر بگیرد (به جز تعریف آن در سازنده). Kotlin به شما امکان می دهد انواع را دقیقاً برای این مورد تعریف out ، و می تواند اطلاعات اضافی در مورد محل استفاده از انواع بی خطر استنتاج کند. به طور مشابه، میتوانید انواعی in برای انواع عمومی تعریف کنید که فقط به متدها منتقل میشوند و برگردانده نمیشوند. این به کاتلین اجازه می دهد تا بررسی های بیشتری را برای ایمنی کد انجام دهد.
انواع in و out دستورالعمل هایی برای سیستم نوع کاتلین هستند. توضیح کل سیستم نوع خارج از محدوده این بوت کمپ است (بسیار درگیر است). با این حال، کامپایلر انواعی را که به طور مناسب in و out علامت گذاری نشده اند، پرچم گذاری می کند، بنابراین باید در مورد آنها بدانید.
مرحله 1: یک نوع خارج را تعریف کنید
- در کلاس
Aquarium،T: WaterSupplyبه یک نوعoutتغییر دهید.
class Aquarium<out T: WaterSupply>(val waterSupply: T) {
...
}- در همان فایل، خارج از کلاس، یک تابع
addItemTo()که انتظار یکAquariumofWaterSupplyدارد، اعلام کنید.
fun addItemTo(aquarium: Aquarium<WaterSupply>) = println("item added")- از
genericsExample()addItemTo()فراخوانی کنید و برنامه خود را اجرا کنید.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
addItemTo(aquarium)
}⇒ item added
Kotlin میتواند اطمینان حاصل کند که addItemTo() هیچ کاری از نوع ناامن با WaterSupply عمومی انجام نمیدهد، زیرا به عنوان یک نوع out اعلام شده است.
- اگر کلمه کلیدی
outرا حذف کنید، کامپایلر هنگام فراخوانیaddItemTo()با خطا مواجه میشود، زیرا کاتلین نمیتواند اطمینان حاصل کند که شما هیچ کاری ناامن با نوع انجام نمیدهید.
مرحله 2: نوع in را تعریف کنید
نوع in مشابه نوع out است، اما برای انواع عمومی که فقط به توابع منتقل میشوند، برگردانده نمیشوند. اگر سعی کنید یک نوع in را برگردانید، یک خطای کامپایلر دریافت خواهید کرد. در این مثال شما یک نوع in را به عنوان بخشی از یک رابط تعریف می کنید.
- در Aquarium.kt ، یک Interface
Cleanerتعریف کنید که یکTعمومی را می گیرد که بهWaterSupplyمحدود می شود. از آنجایی که از آن فقط به عنوان یک آرگومان برایclean()استفاده می شود، می توانید آن را به یک پارامترinتبدیل کنید.
interface Cleaner<in T: WaterSupply> {
fun clean(waterSupply: T)
}- برای استفاده از رابط
Cleaner، یک کلاسTapWaterCleanerایجاد کنید که با افزودن مواد شیمیایی،Cleanerبرای تمیز کردنTapWaterپیاده سازی می کند.
class TapWaterCleaner : Cleaner<TapWater> {
override fun clean(waterSupply: TapWater) = waterSupply.addChemicalCleaners()
}- در کلاس
Aquarium،addWater()را بهروزرسانی کنید تا یکCleanerاز نوعTبگیرد و قبل از اضافه کردن آب آن را تمیز کنید.
class Aquarium<out T: WaterSupply>(val waterSupply: T) {
fun addWater(cleaner: Cleaner<T>) {
if (waterSupply.needsProcessing) {
cleaner.clean(waterSupply)
}
println("water added")
}
}- برای ایجاد یک
TapWaterCleaner، یکAquariumباTapWater، کد نمونهgenericsExample()به روز کنید و سپس با استفاده از پاک کننده مقداری آب اضافه کنید. در صورت نیاز از پاک کننده استفاده خواهد کرد.
fun genericsExample() {
val cleaner = TapWaterCleaner()
val aquarium = Aquarium(TapWater())
aquarium.addWater(cleaner)
}کاتلین از اطلاعات نوع in و out استفاده می کند تا مطمئن شود کد شما به طور ایمن از ژنریک استفاده می کند. به راحتی می توان Out و in را به خاطر آورد: انواع out می توان به عنوان مقادیر بازگشتی به بیرون ارسال کرد، in انواع را می توان به عنوان آرگومان به داخل ارسال کرد.

اگر میخواهید بیشتر در مورد انواع مشکلات در انواع و حلهای خارج تحقیق کنید، مستندات آنها را به طور عمیق پوشش میدهد.
در این کار با توابع عمومی و زمان استفاده از آنها آشنا خواهید شد. به طور معمول، هر زمان که تابع آرگومان کلاسی را که دارای نوع عمومی است، می گیرد، ایجاد یک تابع عمومی ایده خوبی است.
مرحله 1: یک تابع عمومی بسازید
- در generics/Aquarium.kt ، یک تابع
isWaterClean()بسازید که یکAquariumمی گیرد. باید نوع عمومی پارامتر را مشخص کنید. یکی از گزینه ها استفاده ازWaterSupplyاست.
fun isWaterClean(aquarium: Aquarium<WaterSupply>) {
println("aquarium water is clean: ${aquarium.waterSupply.needsProcessing}")
}اما این بدان معناست که Aquarium برای فراخوانی آن باید یک پارامتر نوع out داشته باشد. گاهی اوقات out یا in بسیار محدود کننده است زیرا شما باید از یک نوع برای ورودی و خروجی استفاده کنید. میتوانید با عمومی کردن تابع، نیاز out حذف کنید.
- برای عمومی کردن تابع، براکتهای زاویهای را بعد از کلمه کلیدی
funبا نوعTعمومی و هرگونه محدودیت، در این موردWaterSupplyدهید.Aquariumتغییر دهید تا توسطTبه جایWaterSupplyمحدود شود.
fun <T: WaterSupply> isWaterClean(aquarium: Aquarium<T>) {
println("aquarium water is clean: ${!aquarium.waterSupply.needsProcessing}")
}T یک پارامتر نوع برای isWaterClean() است که برای تعیین نوع عمومی آکواریوم استفاده می شود. این الگو واقعاً رایج است، و ایده خوبی است که یک لحظه برای کار کردن با آن وقت بگذارید.
- تابع
isWaterClean()را با مشخص کردن نوع آن در براکت های زاویه درست بعد از نام تابع و قبل از پرانتز فراخوانی کنید.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
isWaterClean<TapWater>(aquarium)
}- به دلیل استنتاج نوع از آرگومان
aquarium، نوع مورد نیاز نیست، بنابراین آن را حذف کنید. برنامه خود را اجرا کنید و خروجی را مشاهده کنید.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
isWaterClean(aquarium)
}⇒ aquarium water is clean: false
مرحله 2: یک روش عمومی با نوع reified ایجاد کنید
شما می توانید از توابع عمومی برای متدها نیز استفاده کنید، حتی در کلاس هایی که نوع عمومی خود را دارند. در این مرحله، یک روش عمومی را به Aquarium اضافه میکنید که بررسی میکند آیا یک نوع WaterSupply دارد یا خیر.
- در کلاس
Aquarium، یک متد بهhasWaterSupplyOfType()اعلام کنید که یک پارامتر عمومیR(Tقبلاً استفاده شده است) را بهWaterSupplyمحدود می کند و اگرwaterSupplyاز نوعRباشد،trueبرمی گرداند. این مانند عملکردی است که قبلاً اعلام کردید، اما در کلاسAquarium.
fun <R: WaterSupply> hasWaterSupplyOfType() = waterSupply is R- توجه کنید که
Rنهایی با رنگ قرمز خط کشیده شده است. نشانگر را روی آن نگه دارید تا ببینید خطا چیست.
- برای انجام یک
is، باید به Kotlin بگویید که نوع reified یا واقعی است و می تواند در تابع استفاده شود. برای انجام این کار، در مقابل کلمه کلیدیfunقرار دهید و در مقابل نوع عمومیRreifiedinlineقرار دهید.
inline fun <reified R: WaterSupply> hasWaterSupplyOfType() = waterSupply is R هنگامی که یک نوع reified شد، می توانید از آن مانند یک نوع معمولی استفاده کنید - زیرا بعد از خط کشی یک نوع واقعی است. این بدان معنی است که شما می توانید با استفاده از نوع بررسی is .
اگر در اینجا reified استفاده نمی کنید، نوع آن به اندازه کافی «واقعی» نخواهد بود که Kotlin بتواند چک ها is مجاز کند. دلیلش این است که انواع غیر اصلاحشده فقط در زمان کامپایل در دسترس هستند و در زمان اجرا توسط برنامه شما قابل استفاده نیستند. در بخش بعدی بیشتر به این موضوع پرداخته می شود.
-
TapWaterبه عنوان نوع عبور دهید. مانند فراخوانی توابع عمومی، روشهای عمومی را با استفاده از براکتهای زاویه با نوع بعد از نام تابع فراخوانی کنید. برنامه خود را اجرا کنید و نتیجه را مشاهده کنید.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
println(aquarium.hasWaterSupplyOfType<TapWater>()) // true
}⇒ true
مرحله 3: ایجاد توابع افزونه
می توانید از انواع reified برای توابع معمولی و توابع افزونه نیز استفاده کنید.
- خارج از کلاس
Aquarium، یک تابع افزونه درWaterSupplyبه نامisOfType()تعریف کنید که بررسی می کند آیاWaterSupplyارسال شده از نوع خاصی است، به عنوان مثال،TapWater.
inline fun <reified T: WaterSupply> WaterSupply.isOfType() = this is T- تابع افزونه را درست مانند یک متد فراخوانی کنید.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
println(aquarium.waterSupply.isOfType<TapWater>())
}⇒ true
با این توابع توسعه، مهم نیست که چه نوع Aquarium باشد ( Aquarium یا TowerTank یا زیر کلاس دیگر)، تا زمانی که Aquarium باشد. استفاده از سینتکس ستاره پرفکتیو راه مناسبی برای تعیین انواع تطابق است. و هنگامی که از یک ستاره پرتاب استفاده می کنید، کاتلین مطمئن می شود که شما نیز هیچ کار ناامنی انجام نمی دهید.
- برای استفاده از پرتاب ستاره،
<*>را بعد ازAquariumقرار دهید.hasWaterSupplyOfType()به عنوان یک تابع افزونه منتقل کنید، زیرا در واقع بخشی از API اصلیAquariumنیست.
inline fun <reified R: WaterSupply> Aquarium<*>.hasWaterSupplyOfType() = waterSupply is R- فراخوانی را به
hasWaterSupplyOfType()تغییر دهید و برنامه خود را اجرا کنید.
fun genericsExample() {
val aquarium = Aquarium(TapWater())
println(aquarium.hasWaterSupplyOfType<TapWater>())
}⇒ true
در مثال قبلی، شما باید نوع عمومی را بهعنوان reified علامتگذاری میکردید و تابع را inline میکردید، زیرا کاتلین باید در مورد آنها در زمان اجرا بداند، نه فقط زمان کامپایل.
همه انواع عمومی فقط در زمان کامپایل توسط Kotlin استفاده می شوند. این به کامپایلر امکان می دهد مطمئن شود که همه چیز را با خیال راحت انجام می دهید. در زمان اجرا همه انواع عمومی پاک می شوند، از این رو پیام خطای قبلی در مورد بررسی یک نوع پاک شده است.
به نظر می رسد که کامپایلر می تواند کد صحیح را بدون حفظ انواع عمومی تا زمان اجرا ایجاد کند. اما به این معنی است که گاهی اوقات کاری انجام می دهید، is بررسی انواع عمومی، که کامپایلر نمی تواند آن را پشتیبانی کند. به همین دلیل است که کاتلین انواع reified یا واقعی را اضافه کرد.
می توانید اطلاعات بیشتری در مورد انواع reified و پاک کردن نوع در اسناد Kotlin بخوانید.
این درس بر روی ژنریک تمرکز داشت که برای انعطافپذیری بیشتر کد و استفاده مجدد آسانتر از آن مهم است.
- کلاس های عمومی ایجاد کنید تا کد را انعطاف پذیرتر کنید.
- برای محدود کردن انواع مورد استفاده در ژنریک، محدودیتهای عمومی اضافه کنید.
- از انواع
inوoutبا ژنریک استفاده کنید تا بررسی نوع بهتری را برای محدود کردن انواع ارسال یا بازگرداندن از کلاسها انجام دهید. - توابع و روش های عمومی را برای کار با انواع عمومی ایجاد کنید. به عنوان مثال:
fun <T: WaterSupply> isWaterClean(aquarium: Aquarium<T>) { ... } - از توابع پسوند عمومی برای افزودن عملکردهای غیر اصلی به یک کلاس استفاده کنید.
- انواع Reified گاهی اوقات به دلیل پاک کردن نوع ضروری هستند. انواع Reified، بر خلاف انواع عمومی، تا زمان اجرا باقی می مانند.
- از تابع
check()برای تأیید اینکه کد شما مطابق انتظار اجرا می شود استفاده کنید. به عنوان مثال:
check(!waterSupply.needsProcessing) { "water supply needs processing first" }
مستندات کاتلین
اگر در مورد هر موضوعی در این دوره اطلاعات بیشتری می خواهید، یا اگر گیر کرده اید، https://kotlinlang.org بهترین نقطه شروع شما است.
- ژنریک ها
- محدودیت های عمومی
- پیش بینی های ستاره ای
- انواع
Inوout - پارامترهای Reified
- پاک کردن را تایپ کنید
- تابع
check().
آموزش های کاتلین
وبسایت https://try.kotlinlang.org شامل آموزشهای غنی به نام Kotlin Koans، یک مترجم مبتنی بر وب ، و مجموعه کاملی از مستندات مرجع با مثالها است.
دوره جسارت
برای مشاهده دوره Udacity در مورد این موضوع، به Kotlin Bootcamp for Programmers مراجعه کنید.
ایده IntelliJ
اسناد IntelliJ IDEA را می توان در وب سایت JetBrains یافت.
این بخش، تکالیف احتمالی را برای دانشآموزانی که در این آزمایشگاه کد به عنوان بخشی از دورهای که توسط یک مربی هدایت میشود، کار میکنند، فهرست میکند. این وظیفه مربی است که موارد زیر را انجام دهد:
- در صورت نیاز تکالیف را تعیین کنید.
- نحوه ارسال تکالیف را با دانش آموزان در میان بگذارید.
- تکالیف را نمره دهید.
مربیان میتوانند از این پیشنهادات به اندازهای که میخواهند استفاده کنند، و باید با خیال راحت هر تکلیف دیگری را که فکر میکنند مناسب است، محول کنند.
اگر به تنهایی از طریق این کدها کار می کنید، از این تکالیف برای آزمایش دانش خود استفاده کنید.
به این سوالات پاسخ دهید
سوال 1
کدام یک از موارد زیر برای نامگذاری یک نوع عمومی مناسب است؟
▢ <Gen>
▢ <Generic>
▢ <T>
▢ <X>
سوال 2
محدودیت در انواع مجاز برای یک نوع عمومی نامیده می شود:
▢ یک محدودیت عمومی
▢ یک محدودیت عمومی
▢ ابهام زدایی
▢ محدودیت نوع عمومی
سوال 3
ریفید یعنی:
▢ تاثیر اجرای واقعی یک شی محاسبه شده است.
▢ یک شاخص ورودی محدود روی کلاس تنظیم شده است.
▢ پارامتر نوع عمومی به یک نوع واقعی تبدیل شده است.
▢ نشانگر خطای راه دور فعال شده است.
به درس بعدی بروید:
برای یک نمای کلی از دوره، از جمله پیوندهایی به دیگر کدها، به "کوتلین بوت کمپ برای برنامه نویسان: به دوره خوش آمدید" مراجعه کنید.