پارامتر و آرگومان
پارامترها، دادههای خامی هستند که، تابع آنها را پردازش میکند و سپس اطلاعاتی را که به دنبال آن هستید، در اختیار شما قرار میدهد. فرض کنید پارامترها مانند اطلاعاتی هستند که، شما به یک کارمند میدهید که بر طبق آنها کارش را به پایان برساند. یک تابع میتواند هر تعداد پارامتر داشته باشد. هر پارامتر میتواند از انواع مختلف داده باشد. در زیر یک تابع با N پارامتر نشان داده شده است :
fun functionName(param1: datatype , param2: datatype , ... paramN: datatype) { code to execute; }
پارامترها، بعد از نام تابع و بین پرانتزها قرار میگیرند. بر اساس کاری که تابع انجام میدهد، میتوان تعداد پارامترهای زیادی به تابع اضافه کرد. بعد از فراخوانی یک تابع باید آرگومانهای آن را نیز تأمین کنید. آرگومانها، مقادیری هستند که به پارامترها اختصاص داده میشوند. ترتیب ارسال آرگومانها به پارامترها مهم است. عدم رعایت ترتیب در ارسال آرگومانها باعث به وجود آمدن خطا میشود. اجازه بدهید که یک مثال بزنیم :
1: func calculateSum(number1: Int, number2: Int) -> Int 2: { 3: return number1 + number2 4: } 5: 6: print("Enter the first number: ", terminator:"") 7: var num1 = Int(readLine()!) 8: print("Enter the second number: ", terminator:"") 9: var num2 = Int(readLine()!) 10: 11: print("Sum = ", calculateSum(number1: num1! , number2: num2!))
Enter the first number: 10 Enter the second number: 5 Sum = 15
در برنامه بالا یک تابع به نام ()calculateSum (خطوط 4-1) تعریف شده است که وظیفه آن جمع مقدار دو عدد است. چون این تابع مقدار دو عدد صحیح را با هم جمع میکند، پس نوع برگشتی ما نیز باید Int باشد. تابع دارای دو پارامتر است که اعداد را به آنها ارسال میکنیم. به نوع دادهای پارامترها توجه کنید. هر دو پارامتر یعنی number1 و number2 مقادیری از نوع اعداد صحیح (Int) دریافت میکنند. در بدنه تابع دستور return نتیجه جمع دو عدد را بر میگرداند. در داخل تابع ()main برنامه از کاربر دو مقدار را درخواست میکند و آنها را داخل متغیرها قرار میدهد. حال تابع را که آرگومانهای آن را آماده کردهایم فراخوانی میکنیم. مقدار num1 به پارامتر اول و مقدار num2 به پارامتر دوم ارسال میشود. حال اگر مکان دو مقدار را هنگام ارسال به تابع تغییر دهیم (یعنی مقدار num2 به پارامتر اول و مقدار num1 به پارامتر دوم ارسال شود) هیچ تغییری در نتیجه تابع ندارد چون جمع خاصیت جابه جایی دارد.
فقط به یاد داشته باشید که باید ترتیب ارسال آرگومانها هنگام فراخوانی تابع دقیقاً با ترتیب قرار گیری پارامترها تعریف شده در تابع مطابقت داشته باشد. بعد از ارسال مقادیر 10 و 5 به پارامترها، پارامترها آنها را دریافت میکنند. به این نکته نیز توجه کنید که نام پارامترها طبق قرارداد به شیوه کوهان شتری یا camelCasing (حرف اول دومین کلمه بزرگ نوشته میشود) نوشته میشود. در داخل بدنه تابع (خط 3) دو مقدار با هم جمع میشوند و نتیجه به تابع فراخوان (تابعی که تابع ()calculateSum را فراخوانی میکند) ارسال میشود.
در درس آینده از یک متغیر برای ذخیره نتیجه محاسبات استفاده میکنیم ولی در اینجا مشاهده میکنید که میتوان به سادگی نتیجه جمع را نشان داد (خط 3). در خط 9-6 از ما دو عدد که قرار است با هم جمع شوند درخواست میشود.
در خط 11 تابع ()calculateSum را فراخوانی میکنیم و دو مقدار صحیح به آن ارسال میکنیم. دو عدد صحیح در داخل تابع با هم جمع شده و نتیجه آنها برگردانده میشود. مقدار برگشت داده شده از تابع به وسیله تابع ()print نمایش داده میشود (خط 11). در برنامه زیر یک تابع تعریف شده است که دارای دو پارامتر از دو نوع دادهای مختلف است:
1: func showMessageAndNumber(message: String, number: Int) 2: { 3: print(message) 4: print("Number = \(number)") 5: } 6: 7: showMessageAndNumber(message:"Hello World!", number:100)
Hello World! Number = 100
در مثال بالا یک تابع تعریف شده است که اولین پارامتر آن مقداری از نوع رشته و دومین پارامتر آن مقداری از نوع Int دریافت میکند. تابع به سادگی دو مقداری که به آن ارسال شده است را نشان میدهد. در خط 7 تابع را اول با یک رشته و سپس یک عدد خاص فراخوانی میکنیم. حال اگر تابع به یکی از دو صورت زیر فراخوانی میشد :
showMessageAndNumber(message:100, number:"Hello World!")
showMessageAndNumber(number:100, message:"Hello World!")
در برنامه خطا به وجود میآمد. چون در حالت اول، عدد 100 به پارامتری از نوع رشته و رشته !Hello World به پارامتری از نوع اعداد صحیح ارسال میشد. و در حالت دوم هم ترتیب ارسال آرگومان ها رعایت نشده است. این نشان میدهد که ترتیب ارسال آرگومانها به پارامترها هنگام فراخوانی تابع، از لحاظ نوع و پس و پیش بودن، مهم است.
ممکن است که این سوال برایتان پیش آمده باشد که آیا هیچ راهی برای ارسال آرگومان ها، بدون رعایت ترتیب (نه نوع) آنها وجود ندارد؟ جواب این است که، امکان ارسال بدون رعایت ترتیب وجود دارد ولی آن هم با شرایطی خاص. به مثال ابتدای درس بر می گردیم و خط 1 آن را به صورت زیر تغییر می دهیم:
func calculateSum(_ number1: Int, _ number2: Int) -> Int
همانطور که مشاهده می کنید، ما قبل از نام پارامترها از علامت _ استفاده کرده ایم. این کار باعث می شود که ما در هنگام فراخوانی تابع، لازم نباشد که نام پارامترها را ذکر کنیم، یعنی می توانیم خط 11 همین مثال را به صورت زیر بنویسیم:
print("Sum = ", calculateSum(num1! , num2!))
حال چون پارامترهای این تابع هر دو یکسان و از نوع Int هستند، در نتیجه خط بالا را به صورت زیر هم بنویسیم، فرقی نمی کند:
print("Sum = ", calculateSum(num2! , num1!))
در آن مثال دو عدد از نوع Int به پارامترها ارسال کردیم که ترتیب ارسال آنها چون هر دو پارامتر از یک نوع بودند مهم نبود. ولی اگر پارامترهای تابع دارای اهداف خاصی باشند ترتیب ارسال آرگومانها مهم است.
func showPersonStats(age: Int, height: Int) { print("Age = \(age)") print("Height = \(height)") } //Using the proper order of arguments showPersonStats(age: 20, height:160) //Acceptable, but produces odd results showPersonStats(height: 160, age: 20)
در مثال بالا، نشان داده شده است که حتی اگر تابع دو آرگومان با یک نوع دادهای قبول کند، باز هم بهتر است ترتیب بر اساس تعریف پارامترها رعایت شود. به عنوان مثال، در اولین فراخوانی تابع بالا اشکالی به چشم نمیآید، چون سن شخص 20 و قد او 160 سانتی متر است. اگر آرگومانها را به ترتیب ارسال نکنیم سن شخص 160 و قد او 20 سانتی متر میشود که به واقعیت نزدیک نیست. دانستن مبانی مقادیر برگشتی و ارسال آرگومانها باعث میشود که شما توابع کارآمدتری تعریف کنید. تکه کد زیر نشان میدهد که، شما حتی میتوانید مقدار برگشتی از یک تابع را به عنوان آرگومان به تابع دیگر، ارسال کنید.
func myFunction() -> Int { return 5 } func anotherFunction(number: Int) { print(number) } // Codes skipped for demonstration anotherFunction(number: myFunction())
5
چون مقدار برگشتی تابع ()myFunction عدد 5 است و به عنوان آرگومان به تابع ()anotherFunction ارسال میشود، خروجی کد بالا هم عدد 5 است. حال که با مقدار برگشتی از تابع و مفاهیم پارامتر و آرگومان، آشنا شدید، بهتر است در همین درس به انواع حالت های تعریف تابع در Swift اشاره کنیم. در Swift یک تابع می تواند دارای پارامتر یا مقدار برگشتی باشد یا نباشد. ساده ترین حالت تعریف یک تابع این است که نه مقدار برگشتی داشته باشد و نه پارامتر :
fun functionName() { // Some Code }
حالت دیگر این است که پارامتر داشته باشد و مقدار برگشتی نداشته باشد :
fun functionName(parameters) { // Some Code }
نوع دیگر تعریف تابع این است که پارامتر نداشته باشد ولی مقدار برگشتی داشته باشد:
fun functionName() -> returntype { return value }
و روش آخر تعریف تابع هم این است که هم مقدار برگشتی داشته باشد و هم پارامتر :
fun functionName(parameters) -> returntype { return value }
در دو حالت آخر حتما باید از کلمه کلیدی return در بدنه تابع استفاده کنید.