Scope Function ها در کاتلین
در این پست در رابطه با Scope Function ها در کاتلین صحبت خواهم کرد. در کتابخانه استاندارد کاتلین، تعدادی فانکشن وجود دارد با نام های let, run, with, apply و also که به Scope Function ها معروف هستند. فانکشن هایی که به شما کمک می کنند یک قلمرو برای یک شی ایجاد کنید. خوب این به چه معنی است؟
(در این پست و برای سادگی هر چه بیشتر، از کامپلیلر آنلاین کاتلین به آدرس https://play.kotlinlang.org استفاده می کنم)
فرض کنید کلاسی در کاتلین دارین به این صورت:
class Person(var firstName:String, var lastName:String, var age:Int, var webSite:String, var telegram:String)
و حالا یک شی از این کلاس ایجاد می کنیم:
val person = Person("Behnam", "Khani", 0, "", "")
منتها بنا به هر دلیلی، اطلاعات سن، وب سایت و آدرس تلگرام این کاربر را نداریم. ولی کمی جلوتر، این کاربر سن، وب سایت و آدرس تلگرامش را هم وارد میکند. بنابراین لازم است این اطلاعات را به شی ای که ایجاد کرده ایم اضافه کنیم.
دو راه برای این کار وجود دارد:
روش اول:
روش اول این است که به ازای هر خاصیت، یکبار نام شی را صدا بزنیم:
person.age = 35 person.webSite = "code-academy.net" person.telegram = "t.me/codeacademy_official"
روش دوم:
روش دوم استفاده از Scope Function هاست. همانطور که گفتم Scope Function به شما کمک می کند برای یک شی، یک قلمرو ایجاد کنیم و در داخل قلمرو این شی، به راحتی به شی دسترسی داشته باشیم، به این صورت:
person.let{ it.age = 35 it.webSite = "code-academy.net" it.telegram = "t.me/codeacademy_official" }
در این مثال، از Scope Function ای با نام let استفاده کرده ام. همانطور که می بینید ابتدا نام شی را آوردم ام (person)، سپس نقطه و بعد از آن اسکوپ فانکشن let و سپس یک بدنه مشخص کرده ام. این بدنه در واقع قلمرو شی person است. در این قلمرو، شی person با استفاده از کلمه it در دسترس است.
بنابراین وقتی در این قلمرو کلمه it را تایپ می کنیم، شبیه به این است که person را وارد کرده ام. در نتیجه به تمام متدها و خاصیت های قابل دسترس این شی، دسترسی خواهم داشت.
حالا اگر خاصیت های شی person را پرینت کنیم، می بینید که ویرایش اطلاعات به درستی انجام شده است:
println(person.firstName) println(person.lastName) println(person.age) println(person.webSite) println(person.telegram)
پس منظور از Scope Function ها یا فانکشن های قلمرو در کاتلین، چیزی شبیه به این مثال است. فانکشن هایی که یک قلمرو بر روی یک شی ایجاد می کنند. شاید این سوال به ذهنتان برسد که فایده استفاده از فانکشن اسکوپ ها چیست؟ سوال خوبیه!
اسکوپ فانکشن ها در کاتلین قرار نیست بر روی Performance کد ما تاثیری داشته باشند. در واقع قرار است از Scope Function استفاده کنیم تا کد خواناتری داشته باشیم. شاید در نگاه اول این خوانایی به چشم نیاید. ولی هرچه برنامه شما بزرگتر و تعداد خط های برنامه بیشتر می شوند، کاربرد Scope Function بیشتر به چشم می آید. چرا که با استفاده از Scope Function ها، برنامه شما در قالب قلمروهای مختلف تعریف می شود. در واقع با یک نگاه متوجه می شوید که هر قلمرو (کد)، مربوط به کدام شی است.
(من که بشخصه عاشق این امکان کاتلین هستم، واقعا خوانایی کد رو بالاتر میبره، هر چه کدتون بیشتر بشه، بیشتر به این حرفم اعتقاد خواهید داشت)
نکته: دقت کنید که به شی person که قبل از let آمده است، Receiver گفته می شود. Receiver می تواند هر چیزی باشد، از متغیرهای ساده بگیر تا ویجت های اندروید مثل EditText
تا اینجا در مورد Scope Function ای با نام let صحبت کردم و ممکن است سوال بعدی شما این باشد که فانکشن های دیگر مثل run, with, apply و also قرار است چه کاری انجام دهند.
خوب در واقع اینها هم نوعی Scope Function یا فانکشن قلمرو در کاتلین هستند و کاری تقریبا مشابه let انجام میدهند. یعنی یک قلمرو بر روی شی ایجاد می کنند. ولی تفاوت هایی هم وجود دارد که در ادامه در مورد آنها صحبت می کنم.
Scope Function ای به نام also
قبل از اینکه در رابطه با also صحبت کنم، بهتر است بدانید که let علاوه بر اینکه یک قلمرو ایجاد می کند، می تواند مقدارِ آخرین دستور قلمرو را برگرداند. به عنوان مثال، در برنامه قبلی، می توانیم یک رشته به این صورت برگردانیم:
val result = person.let{ it.age = 35 it.webSite = "code-academy.net" it.telegram = "t.me/codeacademy_official" "Changes has been applied!" } print(result)
همانطور که می بینید این عبارت در خروجی چاپ می شود:
"Changes has been applied!"
پس نتیجه میگیریم let هم یک قلمرو برای شی مورد نظر ایجاد کرده و هم آخرین مقدار را برگردانده است.
حالا برگردیم سراغ also. همانطور که گفتم also هم یک قلمرو برای شی ما ایجاد می کند. ولی تفاوتش با let این است که بجای برگرداندن مقدار آخرین دستور، خود شی را بر میگرداند. در واقع also یک قلمرو ایجاد می کند و در نهایت Receiver را برمیگرداند (همان شی ای که بر روی آن قلمرو ایجاد کرده بود).
بیایید همان برنامه قبل را با استفاده از also پیاده سازی کنیم:
val result = person.also{ it.age = 35 it.webSite = "code-academy.net" it.telegram = "t.me/codeacademy_official" } print(result)
اگر این برنامه را اجرا کنیم، میبینید که چیزی شبیه به این نمایش می دهد:
Person@5a07e868
این چیزی که میبینید در واقع آدرس شی person است که نمایش داده شده است. یعنی الان می توانید از طریق result به person دسترسی داشته باشید.
اسکوپ فانکشنی به نام apply
این اسکوپ فانکشن دیگه خیلی کار رو راحت کرده! با apply حتی لازم نیست که دیگه از it استفاده کنید:
val result = person.apply{ age = 35 webSite = "code-academy.net" telegram = "t.me/codeacademy_official" }
همانطور که میبینید این بار از apply استفاده کردم و برنامه به درستی کار می کند. در نظر داشته باشید که apply همانند also، در نهایت همان شی (Receiver) را بر میگرداند.
اسکوپ فانکشنی به نام run
حالا شاید بخواهید چیزی مابین apply و let داشته باشید. یعنی قلمرویی بخواهید برای یک شی ایجاد کنید که شبیه apply نیازی به it نداشته باشد و همینطور شبیه به let مقدار آخرین دستور را برگرداند. برای اینکار از run مشابه زیر استفاده می کنیم:
val result = person.run{ age = 35 webSite = "code-academy.net" telegram = "t.me/codeacademy_official" "Changes has been applied!" }
نکته: در run و apply در واقع کلمه کلیدی this را می توانید به صورت اختیاری استفاده کنید. یعنی کد مربوط به قلمرو run یا apply را می توانید به این صورت هم بنویسید:
val result = person.run{ this.age = 35 this.webSite = "code-academy.net" this.telegram = "t.me/codeacademy_official" "Changes has been applied!" } print(result)
پس می توانید در قلمروهای run و apply به صورت اختیاری از this استفاده کنید. ولی نکته ای که وجود دارد این است که ممکن است انجام این کار، از خوانایی کد شما کم کند. چراکه اگر this را حذف کنید، تشخیص اینکه فرضا فانکشنی، فانکشن Receiver است یا یک فانکشن دیگر، سخت خواهد بود!
در نهایت with شبیه به apply کار می کند ولی با این تفاوت که از with زمانی استفاده کنید که receiver از نوع non-nullable است. در مورد انواع Nullable و Non-Nullable در دوره برنامه نویسی اندروید صحبت کردم. Nullable نوع داده ای بود که مقادیر Null هم قبول می کرد.
خلاصه:
به صورت خلاصه Scope Function ها به ما در بالا بردن خوانایی کد به شدت کمک می کنند. در شکل زیر می بینید که از it و this در کدام قلمرو استفاده می شود.
نوبت شما:
تحقیق کنید تفاوت it و this در کاتلین چیه!؟ نتیجه تحقیقتو همین زیر بنویس…
نویسنده: بهنام خانی
درباره بهنام خانی
زمانی که تصمیم گرفتم برنامه نویسی را شروع کنم، متوجه شدم که نیاز است زمان زیادی را صرف پیدا کردن منابع مختلفی کنم و با کنار هم قرار دادن مطالب این منابع و کشف ارتباط مطالب با هم، در مورد برنامه نویسی تخصص پیدا کنم. بنابراین بعد از اینکه برنامه نویسی را یاد گرفتم و چند سالی پروژه های مختلف نرم افزاری را پیاده سازی کردم، تدریس را هم به عنوان یک علاقه شروع کردم. پس از چند سال تدریس، تصمیم به ساخت آموزش های ویدیویی گرفتم که بتوانم با زبانی ساده، سریع و کاربردی، حاصل مطالعات و تجربیات بازار کار را در اختیار علاقه مندان به طراحی سایت و اپلیکیشن قرار دهم.
نوشته های بیشتر از بهنام خانی