ICT_NoteTaking
ICT_NoteTaking
خواندن ۵ دقیقه·۵ سال پیش

Scope Function IN Kotlin - بخش اول مباحث پایه

قبل از اینکه بخوام شروع کنم این نکته رو باید بگم که من مبتدی هستم و خودم در حال یادگیریم بنابراین ممکنه اشکلاتی در این پست باشه، البته این پست بیشتر ترجمه هستش و چیزی من متوجه میشم از یه متن انگلیسی رو با شما به اشتراک میزارم. (منظورم بیشتر اینه که فول نیستم زبان انگلیسی ) منابع مورد استفاده در این پست رو در آخر قرار میدم. امیدوارم بتونیم در کنار هم چیزی به دانش مون اضافه کنیم.

کتابخانه های استاندارد کاتلین یه سری فانکشن داره که هدفشون اجرای یک بلوک کد در چارچوب یک شی هستش. وقتی که چندین عملکرد رو روی یک شی یا یک عبارت لامبدا ارائه میدیم، دامنه موقت (temporary scope) را تشکیل میدهیم. در این دامنه ما میتونیم بدون نام اون آبجکت به اون آبجکت دسترسی داشته باشیم. که این مدل توابع رو Scope Function می نامیم. پنج مورد از این توابع وجود داره.

let , run, with, apply , also

تمام این 5 توابع همان کار رو انجام میدند، که در بالا گفته شده.(اجرای یک بلوک کد در چارچوب یک شی)

** جلوتر چندتا مثال از این توابع زدم ،فعلا کاری به این 5 تابع نداشته باشید تا هرکدوم رو در جای خودش توضیح بدم. چون یه سری پیش نیاز کلی داره.
** تو بعضی جاها هم متن اصلی و فارسی رو با هم میزارم بعضی وقت ها متن اصلی فهمش راحت تره تا نسبت به فارسی

چیزی که بین اینها متفاوته این است چجوری شی در داخل بلوک در دسترس میباشند و نتیجه رو به چه صورت برمیگردونند

What's different is how this object becomes available inside the block and what is the result of the whole expression.

یه نمونه از Scope Function با استفاده از let

Scope Function : let
Scope Function : let

اجرا :

Person(name=Alice, age=20, city=Amsterdam) Person(name=Alice, age=21, city=London)

اگر همین کار رو بدون let انجام بدیم ، باید یه متغیر جدید بسازیم و هر زمان که بخوایم ازش استفاده کنیم باید نام اون متفییر رو صدا/تکرار کنیم.

بدون استفاده از let
بدون استفاده از let

توابع دامنه هیچ توانایی فنی جدیدی رو ارائه نمیده ، اما باعث میشه کد مون رو مختصر و قابل خواندی تر کنه.

از اونجای ماهیت scope function ها عملکرد مشابه ای داره انتخاب صحیح این توابع ممکنه مشکل باشه.

این انتخاب عمدتا به هدف ما و قوام استفاده از اون تابع در پروژه بستگی داره، توضیحاتی که جلوتر قراره ارائه بدم درباره تمایز بین توابع دامنه و قراردادهای مربوط به کارکرد آنها می باشد.


تمایزات - Distinctions

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

  • The way to refer to the context object

اینکه یه ابجکت از چه طریقی به context وصل بشه (this or it)

  • The return value.

یا اینکه طریقه برگشت به چه صورت باشه.

بریم ببینیم قضیه چیه :


Context object: this or it

در داخل لامبدا یک تابع دامنه ، زمینه (context) آبجکت به جای استفاده از نام اون آبجکت برای دسترسی بهش از طریق یک مرجع کوتاه قابل دسترس هستش. هر تابع دامنه با استفاده از دو روش به زمینه (context) دسترسی داره. به عنوان گیرنده (receiver) لامبدا یا همون this یا بصورت آرگومان لامبدا که it میشه. هر کدوم از این ها، this و it ویژگی های یکسانی دارند.

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


this

فعلا در بخش تمایزات هستیم و اگه یادتون باشه گفتیم که دو تفاوت اصلی بین scope function ها است

که یکیش " The way to refer to the context object " بود.

سه تا از توابع با استفاده از کلمه کلیدی this به زمینه یا context وصل میشند که عبارت اند از run, with و apply

از این رو در داخل لامبدای این 3 تابع، اجزای شی در دسترس ما هست. (البته اینو هم بگم که بغییر اجزای شی به چیزهای دیگه هم میتونیم دسترسی داشته باشیم یا اینکه یه ویژگی یا متد خاصی رو فراخوانی کنیم که در بخش توضیحات هر تابع بهتون نشون میدم) ما میتونیم کلمه کلیدی this رو زمانی که میخوایم به اعضای یک آجکت/متد و ... دسترسی داشته باشیم رو حذف کنیم. که در این حالت کدمون کوتاه تر میشه . از طرف دیگر اگر کلمه کلیدی this حذف شود تفکیک بین اعضای گیرنده (receiver members) و اشیای خارجی (external objects) یا فانکشن ها سخت است.

بنابراین داشتن context object به عنوان گیرنده/ receiver برای لامبداهایی که عمدتا رو اعضای شی کار میکنند توصیه میشود. که میتونید یک متد رو فراخوانی یا مقداری رو برای ویژگی (properties) اختصاص بدید.

در مثال بالا هم میتونید از age در داخل لامبدا استفاده کنید و هم اینکه بصورت this.age استفاده کنید - داخل کامنت تصویر مشخصه.


it

در let و also - به context object به عنوان آرگومان لامبدا در اختیار خود دارید. اگر نام آرگومان مشخص نشده باشد ، با استفاده از پیش فرض ضمنی نام ( it )به اجزا دسترسی دارید. همانند this نمیتونیم بطور مستقیم توابع یا خصوصایت (properties) یک آبجکت دسترسی داشته باشیم - مثل مثال بالا که مستقیم age استفاده کردیم در توابع let و also باید بصورت it.age دسرسی پیدا کنیم. وقتی که آرگومان یه تابع رو نیاز داریم بهتر که از این توابع یا it استفاده کنیم. و همچنین زمانی که چندین متغیر برای یک بلوک از کد در حال استفاده هستید it توصیه میشود.

همانطوری که در مثال بالا می بینید مقدار برگشتی در تابع getRandomInt از طریق it به آرگومان متد writeToLog پاس دادیم. اینجا it$ به عنوان نماینده مقدار تابع getRandomInt عمل میکنه. که مقدار برگشتی این تابع از نوع Int است.

علاوه بر این ، وقتی شیء زمینه را به عنوان یک آرگومان منتقل می کنیم ، می توانید یک نام دلخواه برای context object در داخل دامنه تهیه کنید.

در مثال بالا به جای it از value که یک اسم دلخواه است استفاده میکنیم و این نکته رو مد نظر داشته باشد که بعد اسم دلخواه باید <- استفاده کنیم که بصورت یک فلش است.


رسیدیم به دومین تفاوت Scope Function ها یعنی مقادیر بازگشتی / Return value

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

  • apply and also return the context object.
  • let, run, and with return the lambda result.

این دو گزینه به ما این امکان می دهد بسته به آنچه در کد بعدی انجام می دهیم عملکرد مناسب را انتخاب کنیم.

Context object

مقدار بازگشتی در apply و also به خود زمینه (context) اون آبجکت مرتبط است. میتونیم زنجیره ای عملکردها که به context اشاره دارند رو مورد استفاده قرار بدیم.

تمام موارد بالا also - apply - sort - اشاره دارند به mutableListOf که بصورت زنجیره ای به هم متصل هستند.

همچنین میتونیم در عبارات برگشتی از توابع برگشتی از شی زمینه استفاده کرد.

مثال بالا رو در بخش it توضیح دادم.


Lambda result

توابع let - run و also نتیجه یک عبارت لامبدا رو برمیگردونه، بنابراین هنگام اختصاص دادن نتیجه به یک متغیر ، میتونیم زنجیره ای از عملیات رو که میخوایم روی اون متغیر انجام بدیم رو بهش اعمال کنیم.

مثال بالا به این صورت هست که it حکم اون متغیری رو داره که میخوایم عملیات روش انجام بدیم ، حالا میتونه شامل یک یا چند عملیات باشه. که در این مثال ما به دنبال مغادیری هستیم که آخرشون به 'e' ختم میشوند. دقت داشته باشید که روی مقدار بازگشتی داریم تمرکز میکنیم و مقدار بازگشتی ما در این مثال از نوع Int هستش.

علاوه بر این ، شما می توانید مقدار بازگشت را نادیده بگیرید و از یک تابع دامنه برای ایجاد دامنه موقتی برای متغیرها استفاده کنید.


خب بخش اول تموم شد، چون نمیخوام پست زیاد طولانی بشه در بخش دوم میرسیم به توضیح خود Scope Function ها - اینم از آخرین پست سال 98 بخش دومش میفته سال بعد ?

نمیدونم توضیحات کمکی بهتون کرده یا نه ولی امیدوارم مفید واقع شده باشه. کمی کاستی یا سوالی داشت کامنت بزارید درحد سوادم پاسخگو هستم. لینک سایر بخش هم رو قرار میدم تا دسترسی واستون راحت باشه + لینک منابع این قسمت.
https://virgool.io/@omiddeadlive/scope-function-in-kotlin-let-بخش-دوم-xyoazcq6kvvr



https://kotlinlang.org/docs/reference/scope-functions.html


قشنگ ترین حس و حال های دنیار رو براتون آرزو میکنم در سال 99

دامنه توابعscope functionstandard functionsکاتلینkotlin
جزوات و نت بردای‌های من از دوره‌های ICT بیشتر در t.me/ICT_NoteTaking
شاید از این پست‌ها خوشتان بیاید