توابع تو در تو یا nested function در سوئیفت

مقدمه

ما امروز در این مقاله توضیحی در مورد توابع تو در تو یا nested function خواهیم داد

توابع تو در تو
توابع تو در تو


#کپی رایت


هرگونه کپی برداری از این مطلب بدون ذکر نام نویسنده شرعا حرام بوده و در صورت مشاهده چنین موردی از مراجع قضایی پیگیری میکنیم


مدل نوشتاری (syntax) این توابع

func someFunc(){     
     //statement        
     func anotherFunc(){     
      }
      anotherFunc()  
  }

در بالا تابع خارجی را میبینیم (someFunc) که در درون آن تابع anotherFunc قرار دارد لازم به ذکر است که تابع درونی در خارج از بدنه someFunc را نمیتوان call کرد

مثال - ۱ تابع تو در تو بدون بازگشت مقداری

func outputMessage(_ message:String){
        func greeting(){
        print("Hello! \(message)")
        }
        greeting()
   }
outputMesaage("sadegh")

خروجی کد بالا به صورت زیر است

Hello! sadegh

در تابع outputMessage پارامتر message از جنس string میباشد پس از پر کردن آن، برنامه تابع greeting را صدا میکند و تابع greeting نیز بعد از Hello! پارامتر تابع خارجی را در آن جایگذاری میکند

توجه : شما نمیتوانید تابع greeting را خاج از بدنه تابع outputMessage صدا کنید


به توضیحات توجه کنید

ما وقتی میخواهیم تابعی بسازیم اون رو با کلمه func مینویسیم و اگر لازم باشید مقدار بازگشتی و پارامتر به آن میدهیم

به این تابع نگاه کنید

func multiplication(number:Int) -> Int {
return number*2
}

مدل نوشتاری تابع بالا به اینصورت هستش

(Int)->(Int)

حالا تابعی مینویسیم که دو پارامتر بگیرد و یک عدد برگرداند

(Int,Int)->(Int)

فکر میکنم با این مدل نوشتاری آشنا شدید ، حالا به مثال پایین توجه کنید

مثال - ۲ تابع تو در تو با پارامتر و بازگشت مقدار

func operate(_ symbol:String) -> (Int,Int) -> (Int){
func plus(num1:Int,num2:Int)->Int{
return num1 + num2
}
func subtraction(num1:Int,num2:Int) -> Int{
return num2 - num1
}
let operation = symbol == "+" ? plus : subtraction
return operation
}
let op = operate("-")
let rea = op(2, 7)
print(rea)

اگر نگاهی به تابع بندازیم تابع operate را میبینیم که یک پارامتر دارد از جنس String اما به مقدار بازگشتی آن توجه کنید در واقع مقدار بازگشتی آن یه تابع است که دو پارامتر از جنس Int دارد و به ما یک Int برمیگرداند

یعنی عملا در خط اول ما دو تابع با شکل های نوشتاری متفاوت میبینیم

حالا دو تابع جمع و تفریق که هر دوی این توابع در ورودی خود دو عدد میگیرند یک Int برمیگردانند

اما شاید در کد بالا یک چیز جدید دیده باشید و آن هم این است

let operation = symbol == "+" ? plus : subtraction 

کد بالا را TernaryOperator میگویند دقیقا مانند دستور شرطی if هست اما مدل کوتاه تر آن هست

در این کد میگوییم اگر symol برابر "+" بود ،تابع plus را صدا کن و مقدارش را در operation بریز ،اگر غیر از این بود تابع subtraction را صدا کن و مقدارش را در operation بریز

مدل نوشتاری همچین دستور شرطی چگونه است ؟ به کد زیر دقت کنید

let res = اگر شرط درست نبود : اگر شرط درست بود  ?  مقدار 

اما شاید برای شما سوال پیش بیاید که چرا در کد بالا توابع بدون پارامتر هاشون صدا شدن ، سوال خوبی است

جواب : چون تابع بیرونی (operate) یک تابع برمیگرداند که دقیقا باید مقدار خروجی تابع بیرونی با پارامتر و خروجی تابع درونی یکی باشه

البته شما به غیر از مدل صدا کردن بالا به این صورت هم میتونید صدا کنید

let operation = symbol == "+" ? plus(num1:num2:) : subtraction(num1:num2: )

به بحث برمیگردیم

let operation = symbol == "+" ? plus : subtraction 
return operation 

حالا ما operation را برمیگردانیم که از جنس زیر هستش

(Int,Int)->(Int)

حالا وقته صدا کردن تابع و کار با آن است

let op = operate("+")
let rea = op(2, 7)
print(rea)

متغیری به نام op تعریف میکنیم ، حالا operate را صدا میزنیم و پارامتر آن را پر میکینیم ، اگر یادتون باشه operate تابع (Int,Int)->(Int) را برمیگرداند که همین تابع داخل op ریخته میشه ، بعد از آن متغیری به نام rea میسازیم و در آ تابع op که گفتم بالا از جنس چی هست رو مقدار میدهیم op هم یک . Int برمیگرداند و داخل rea میریزد و در آخر ما آن را چاپ میکنیم


سخنی با برنامه نویسان

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