تعریف تابع
برای جلو گیری از باز نویسی کد ها از توابع استفاده میکنیم همینطور تابع به مرتب شدن و خوانا تر شدن کد های برنامه کمک میکنه.
به طور کلی تابع یه سری داده رو به عنوان ورودی میگیره و بعد از انجام محاسبات لازم نتیجه رو به صورت خروجی نمایش میده، برمیگردونه و یا داده های ورودی رو دستخوش تغییر میکنه.
موضوع تابع و برنامه نویسی تابعی (Functional Programming) در کاتلین به خوبی پشتیبانی میشه و کاتلین در این زمینه قوی عمل کرده.
به تابع ، فانکشن (function) و متد گفته می شود.
به علت گستردگی موضوع توابع مرتبه بالا (higher order functions)، توابع بی نام، عبارت لامبدا ، توابع اکستنشن و توابع خطی (inline functions) رو این مطلب پوشش نمیده و باید در صفحه ی اختصاصی خودشون مطالعه کنید.
برای مطالعه ی موارد ذکر شده میتونید به هر کدوم در مطالب مرتبط پایین همین صفحه مراجعه کنید.
ساختار تابع
فرم کلی:
فرم کلی ساختار یک تابع در تصویر زیرنمایان شده.

۱-بیان کننده ی سطح دسترسی به تابع در پروژه است. سطح دسترسی میتونه private، protected، internal و public باشه. به این کلیدواژه ها کلیدواژه های سطح دسترسی یا access modifier گفته میشه.
توجه:
سطح دسترسی توابع در کاتلین به صورت پیشفرض public است و نیازی به نوشتن نداره.
۲- با استفاده از کلیدواژه ی fun به کامپایلر اعلام میکنیم عبارت یک تابع است.
۳- myFunction اسم تابع است و هر اسمی میتونه باشه.
۴- برای تابع میتونیم پارامتر هایی تعریف کنیم تا هنگام صدا زدن تابع مقادیری به داخل تابع پاس بدیم. مثلا t0: T0 رو در نظر بگیرید t0 اسم دلخواه برای پارامتر و T0 کلاسی از نوع دلخواه برای پارامتر است سپس با یک ویرگول میتونیم پارامتر بعدی که در اینجا t1: T1 است رو برای فانکشن تعریف کنیم. به همین ترتیب هرچندتا پارامتر خواستید میتونید برای تابع تعریف کنید.
توجه:
هنگام استفاده از پارامتر داخل فانکشن در کاتلین، پارامتر val است.
۵- R کلاسیه که تابع بر میگردونه و هر نوعی میتونه باشه
۶- r مقداری از جنس R است که بعد از اجرای کد های داخل تابع با استفاده از کلیدواژه ی return برگردونده میشه.
توجه:
تابع حتما باید مقداری از جنس R برگردونه در غیر این صورت دچار خطای کامپایل میشیم، مگه اینکه R از نوع Unit باشه، در اینصورت نیاری نیست چیزی برگردونده بشه.
توجه:
علاوه بر اخرین عبارت میتونیم از return هرجای تابع که خواستیم استفاده کنیم، در اینصورت بعد از اجرای return تابع متوقف میشه و کد های بعد از return اجرا نمیشه.
مثال:
در مثال بالا اگه عدد زوج نباشه مقدار -1 بر گردونده میشه و ادامه ی کد اجرا نمیشه.
صدا زدن تابع:
برای صدا زدن تابع کافیه اسم تابعو با پارامتر هایی که براش تعریف کردیم بنویسیم:
مثال:
در زیر یک تابع با modifier پیشفرض public مقدار maximum بین دو عددو بر میگردونه.
تعریف overloading
وقتی دو یا چند تابع هم نام با پارامتر های متفاوت تعریف کنیم بهش میگیم overloading
مثال
در بالا تابع max رو با تغییر دادن نوع پارامتر ها overload کردیم.
ویژگی پارامتر ها در توابع
۱- اختصاص دادن مقدار پیشفرض به پارامتر:
هر پارامتری که برای تابع تعریف میکنید میتونید بهش مقدار پیشفرض اختصاص بدید. در اینصورت هنگام صدا زدن تابع اگه مقداری به پارامتر اختصاص نداده باشید ، کامپایلر به صورت خودکار مقدار پیشفرض رو برای پارامتر در نظر میگیره.
مثال:
تعریف تابع:
صدا زدن تابع:
نوشتن اسم پارامتر به صورت آشکار هنگام صدا زدن تابع:
بعد از صدا زدن تابع هنگامی که بخوایم مقداری به پارامتر اختصاص بدیم، میتونیم اسم پارامتر رو به صورت آشکار بنویسیم.
مثال:
تعریف تابع:
صدا زدن تابع:
۳- استفاده از کلیدواژه ی vararg هنگام تعریف پارامتر:
توابع arrayOf ، listOf ، asList و ... با این روش پیادهسازی شدن.
با استفاده از کلیدواژه ی vararg برای پارامتر، هنگام صدا زدن تابع میتونید چندین مقدار به پارامتر اختصاص بدید.
هنگام استفاده از پارامتر در داخل تابع، پارامتر به صورت ارایه ای از مقادیر اختصاص داده شده در میاد.
توجه:
از این کلید واژه فقط برای یک پارامتر میتونید استفاده کنید.
توجه:
معمولا از این کلیدواژه در اخرین پارامتر استفاده میکنن. اگه از این کلیدواژه در اخرین پارامتر استفاده نشه هنگام صدا زدن تابع و اختصاص دادن مقدار به پارامتر باید اسم پارامتر به صورت آشکار نوشته بشه.
مثال:
حساب کردن میانگین اعداد.
تعریف تابع:
صدا زدن تابع:
مثال:
بررسی دفعات تکرار یک کد ASCII در مجموعه ی استرینگ ها.
تعریف تابع:
صدا زدن تابع:
تابع تک عبارتی
اگه داخل تابع فقط یک عبارت داشته باشیم و اون عبارتو میخوایم برگردونیم، به این تابع تک عبارتی یا تابع single expression در کاتلین میگیم.
هنگام تعریف تابع میتونیم از نوشتن بدنه ی تابع {} صرف نظر کنیم و در جلوی تابع علامت = میزاریم.
مثال:
میتونیم از نوشتن نوع کلاسی که تابع برمیگردونه صرف نظر کنیم کامپایلر به صورت خودکار تشخصی میده چه نوعی تابع قراره برگردونه.
مثال:
مثال:
تابع Void
تابع main که برای run کردن پروژه تعریف میکنیم void است.
اگه نوع کلاسی که تابع برمیگردونه Unit باشه تابع void محسوب میشه ، به این توابع در کاتاین تابع Unit Type نیز گفته میشه.
Unit در کاتلین بدون مقدار در نظر گرفته شده ، یک کلاس بدون هیچ عضوی.
مثال:
برای تعریف تابع void در کاتلین میتونیم از نوشتن Unit صرف نظر کنیم. کامپایلر به صورت خودکار تشخیص میده تابع Unit است.
در توابع void میتونیم از return برای متوقف کردن تابع و جلوگیری از اجرای بقیه ی کد ها استفاده کنیم.
مثال:
مثال:
مثال:
مثال:
تابع Infix
توابع until، downTo و step که در حلقه ی for به کار میبریم به صورت infix تعریف شدن.
به تابعی که با کلیدواژه ی infix تعریف میشه، تابع infix میگن.
برای تعریف تابع infix در کاتلین باید قوانین زیر رعایت بشه:
۱-تابع باید عضو کلاس (Member Function) یا تابع اکستنشن باشه.
۲-تابع نباید بیشتر از یک پارامتر داشته باشه.
۳- در پارامتر نباید از vararg استفاده کنیم.
۴- به پارامتر نباید مقدار پیشفرض اختصاص بدیم.
فرم کلی:
صدا زدن تابع:
میتونیم به یکی از دو روش زیر تابع رو صدا بزنیم.
متغیر a رسیور (receiver) و متغیر b مقدار اختصاصی به پارامتر است.
توجه:
متغیر a باید یک آبجکت از کلاسی باشه که براش تابع رو تعریف کردیم.
مثال:
در زیر یک تابع infix تعریف میکنیم تا دوتا String رو به هم زنجیر کنه:
توجه:
کلیدواژه ی this اشاره به آبجکت همون کلاسی داره که تابع رو براش تعریف کردیم.
صدا زدن تابع
مثال:
تابع زیر مانند until عمل میکنه با این تفاوت، بزرگترین عدد هم تو عمل تکرار به حساب میاد.
مثال:
تابع زیر معادل downTo برای حلقه ی for عمل میکنه با این تفاوت کوچکترین عدد تو عمل تکرار حساب نمیشه.
صدا زدن تابع:
توجه:
اجرای تابع infix نسبت به عمل ریاضی، rangeTo و کست کردن اولویت پایین تری داره.
مثلا وقتی عمل ریاضی به عنوان پارامتر برای تابع تعریف میکنیم ابتدا عمل ریاضی اتفاق میفته بعد به عنوان پارامتر به تابع پاس داده میشه.
p until 8 + 5 همون p until (8 + 5) است. ابتدا 8 با 5 جمع میشه بعد به تابع until پاس داده میشه.
توجه:
اجرای تابع نسبت به عملگر های منطقی و in اولویت بالاتری داره.
a && b xor c همون a && (b xor c) است. ابتدا تابع xor اجرا میشه بعد && بررسی میشه.
تابع Generic
به توابعی که پارامتر های جنریک دارن تابع جنریک میگیم.
فرم کلی:
E میتونه هر کلاسی باشه کافیه هنگام صدا زدن تابع نوع کلاسو مشخص کنیم.
Type هم کلاسیه که تابع برمیگردونه و میدونیم که میتونه هر نوعی باشه.
مثال:
صدا زدن تابع:
تابع Tail Recursive
با استفاده از کلیدواژه ی tailrec میتونید به صورت native تابع tail recursive در کاتلین تعریف کنید. tail recursion نوع خاصی از توابع بازگشتی است که صدا زدن تابع داخل خودش باید اخرین عبارت داخل تابع باشه.
توجه:
در تابع tail recursive پس از صدا کردن تابع در داخل خود تابع، هیچ کدی نباید نوشته بشه در غیر این صورت دچار خطای کامپایل میشیم.
مثال:
محاسبه ی فیبوناچی به روش tail recursion.
فرض کنید n = 3. برای n=3 ، a = 0 و b = 1 سپس تابع در داخل خودش صدا زده میشه و n = 2 میشه a = b و b = a + b میشه و به همین منوال این عمل تکرار میشه تا n به 0 برسه در اینجا صدا زدن تابع متوقف میشه.
مثال:
محاسبه ی فاکتوریل به روش tail recursion.
فرض کنید میخوایم 5! حساب کنیم در اینصورت n=5 و result=5*4*3*2*1.
محدوده ی تعریف توابع
یک تابع رو میتونیم:
در فایل کاتلین تعریف کنیم، که بهش میگیم تاپ لول فانکشن (Top Level Function).
میتونیم داخل یک کلاس تعریف کنیم که بهش میگیم ممبر فانکشن (Member Function).
میتونیم داخل یک تابع دیگه تعریف کنیم که بهش میگیم لوکال فانکشن (Local Function).
تاپ لول فانکشن:
ممبر فانکشن:
لوکال فانکشن:
لوکال فانکشن (تابع داخلی) رو فقط داخل تابعی که تعریف کردیم میشه صدا زد.
تابع داخلی در کاتلین میتونه به متغیر های تابع خارجی دسترسی داشته باشه.
فرم کلی:
مثال:
مثال:
خلاصه
-از توابع برای جلوگیری از دوباره نویسی استفاده میشه. همونطور به مرتب و خوانا کردن کد ها کمک میکنه.
-در حالت نرمال توابع از 6 قسمت تشکیل شدن:
۱-کلیدواژه ی سطح دسترسی ۲-کلیدواژه ی fun که مخفف فانکشن است ۳-اسم تابع ۴-پارامتر های تابع ۵-نوعی که تابع بر میگردونه ۶-کلیدواژه ی return برای برگردوندن.
-هرجای تابع که خواستیم میتونیم از return استفاده کنیم. پس از اجرای return تابع متوقف شده و کد های بعد از return اجرا نمیشن.
به تابعی که یک عبارت داشته باشه single expression میگیم.
-توابع void مقداری از Unit بر میگردونن که میتونیم از نوشتنش صرف نظر کنیم
-توابع infix چهارتا قانون دارن که هنگام تعریف باید رعایت بشه:
۱-تابع باید ممبر فانکشن یا اکستنشن باشه. ۲-باید فقط یک پارامتر داشته باشه. ۳-برای پارامتر نباید vararg تعریف کنیم. ۴-به پارامتر نباید مقدار پیشفرض اختصاص بدیم.
-کاتلین به صورت native از تابع tail recursive پشتیبانی میکنه. برای تعریف این تابع کافیه از کلیدواژه ی tailrec استفاده کنیم.
-در توابع tail recursive اخرین عبارت باید صدا زدن تابع داخل خودش باشه و بعدش هیچ کدی نباید نوشته بشه.
-میتونیم توابع رو در سه جا تعریف کنیم: ۱-داخل فایل کاتلین. ۲-داخل کلاس. ۳ داخل یک تابع دیگه.
بحث توابع در کاتلین بسیار گستردس پشتیبانی کاتلین از توابع قویه. در این مطلب به بخشی از توابع پرداختیم، همینطور که بالا گفتم، یه سری از تابعها رو اینجا پوشش ندادم وبراشون مطلب اختصاصی گذاشتم میتونید مطالعه کنید.
موفق باشید.