با عرض سلام و وقت بخیر خدمت کاربران سایت پی وی لرن . و کاربرانی که دوره کامل آموزش Swift را دنبال می کنند. یک تابع مجموعه ای از دستوراتی است که برای انجام یک کار خاص سازماندهی می شوند. یک تابع در Swift می تواند به عنوان یک تابع ساده C به عنوان یک تابع زبان تابع Objective C پیچیده باشد. این توابع همچنین به ما اجازه می دهد که ارزش های پارامترهای محلی و عمومی را به فراخوانی توابع انتقال دهیم. برای آشنایی بیشتر با عملکرد و نحوه کار با توابع در Swift در ادامه ی این مبحث با ما همراه باشید.
در ادامه ی این آموزش شما را با ساختار کار با توابع در Swift و جزئیات آن آشنا خواهیم کرد.
توابع به طور کلی از دو قسمت تشکیل شده اند:
اعلامیه : به کامپایلر در مورد نام تابع، نوع بازگشتی و پارامترها اعلام می شود.
تعریف تابع : این بدنه ی واقعی یک تابع را تعریف می کند.
توابع Swift 4 شامل نوع پارامتر و انواع بازگشتی آن است.
در Swift 4 یک تابع توسط کلید واژه “func” تعریف می شود.
هنگامی که یک تابع به تازگی تعریف شده است، ممکن است یک یا چند مقدار را به عنوان پارامترهای ورودی به تابع برساند.
سپس می توان پارامترهای ورودی را در بدنه تابع بکار برد و یک مقدار خروجی را برگرداند.
هر تابع نامی دارد که با آن نام شناخته می شود، این نام توسط برنامه نویس تعیین می شود.
برای فراخوانی یک تابع باید از نام آن به همراه ارسال مقادیر پارامترهای ورودی به آن استفاده کرد.
آرگومان های ورودی یک تابع باید بر اساس ترتیبی که تعریف شده مقداردهی شوند.
مقادیر بازگشتی را باید به دنبال → تعریف کرد.
ساختار :
1 2 3 4 5 6 7 | func funcname(Parameters) -> returntype { Statement1 Statement2 --- Statement N return parameters } |
مثال زیر نحوه تعریف و فراخوانی یک تابع را نشان می دهد:
1 2 3 4 5 6 | func student(name: String) -> String { return name } print(student(name: "First Program")) print(student(name: "About Functions")) |
نتیجه ی کامپایل و اجرای کد فوق به صورت زیر خواهد بود:
1 2 | First Program About Functions |
برای نمونه یک تابع ساده با نام display تعریف می کنیم تا نحوه ی پاس دادن پارامترها به تابع و چاپ مقدار بازگشتی تابع را نشتن دهیم.
مثال:
1 2 3 4 5 6 7 | func display(no1: Int) -> Int { let a = no1 return a } print(display(no1: 100)) print(display(no1: 200)) |
نتیجه ی کامپایل و اجرای کد فوق به صورت زیر خواهد بود:
1 2 | 100 200 |
Swift 4 پارامترهای توابع انعطاف پذیر و مقادیر بازگشتی آن را از مقادیر ساده تا پیچیده فراهم می کند.
توابع مقادیری را در قالب پارامتر دریافت کرده و پس از انجام تغیراتی روی آن نتیجه را به برنامه ی اصلی برمی گردانند.
مثال:
1 2 3 4 5 6 7 | func mult(no1: Int, no2: Int) -> Int { return no1*no2 } print(mult(no1: 2, no2: 20)) print(mult(no1: 3, no2: 15)) print(mult(no1: 4, no2: 30)) |
نتیجه ی کامپایل و اجرای کد فوق به صورت زیر خواهد بود:
1 2 3 | 40 45 120 |
همچنین می توانید هیچ پارامتری به تابع ارسال نکنید.
سینتکس تابع بدون پارامتر:
1 2 3 | func funcname() -> datatype { return datatype } |
مثال زیر نمونه ای از یک تابع بدون پارامتر را نشان می دهد:
1 2 3 4 | func votersname() -> String { return "Alice" } print(votersname()) |
نتیجه ی کامپایل و اجرای کد فوق به صورت زیر خواهد بود:
1 | Alice |
توابع قابلیت بازگرداندن انواع مقادیر صحیح ، اعشاری و رشته ای را به برنامه اصلی دارند.
در مثال زیر تابعی قرار داده ایم که عملکرد کامل پارامترها و مقادیر بازگشتی را در یک تابع نشان می دهد.
در این مثال برنامه ای نوشته شده که پارامترهایی از نوع اعداد صحیح (int) دریافت می کند.
سپس با مقایسه اعداد با هم کوچکترین و بزرگترین عدد را به برنامه اصلی برمی گرداند:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | func ls(array: [Int]) -> (large: Int, small: Int) { var lar = array[0] var sma = array[0] for i in array[1..<array.count] { if i < sma { sma = i } else if i > lar { lar = i } } return (lar, sma) } let num = ls(array: [40,12,-5,78,98]) print("Largest number is: \(num.large) and smallest number is: \(num.small)") |
نتیجه ی کامپایل و اجرای برنامه ی فوق به صورت زیر خواهد بود:
1 | Largest number is: 98 and smallest number is: -5 |
بعضی از توابع ممکن است آرگومان های داخل تابع را بدون هیچ مقدار بازگشتی اعلام کنند.
در مثال زیر ابتدا مقادیر a و b به پارامترهای ورودی تابع ()sum ارسال می شود.
سپس داخل تابع مقادیر a و b با هم جمع شده و نتیجه در خود تابع چاپ می شود.
بنابراین تابع ()sum هیچ مقداری را بازگشت نمی دهد:
1 2 3 4 5 6 7 8 9 | func sum(a: Int, b: Int) { let a = a + b let b = a - b print(a, b) } sum(a: 20, b: 10) sum(a: 40, b: 10) sum(a: 24, b: 6) |
نتیجه ی کامپایل و اجرای کد فوق به صورت زیر خواهد بود:
1 2 3 | 30 20 50 40 30 24 |
زمانیکه در توابع مقدار بازگشتی را معیین می کنیم مثلا اگر از نوع integer اعلام می کنیم باید در تابع return نیز مقدار را از همان نوع در نظر بگیریم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | func minMax(array: [Int]) -> (min: Int, max: Int)? { if array.isEmpty { return nil } var currentMin = array[0] var currentMax = array[0] for value in array[1..<array.count] { if value < currentMin { currentMin = value } else if value > currentMax { currentMax = value } } return (currentMin, currentMax) } if let bounds = minMax(array: [8, -6, 2, 109, 3, 71]) { print("min is \(bounds.min) and max is \(bounds.max)") } |
نتیجه ی اجرای برنامه ی فوق با playground بصورت زیر خواهد بود:
1 | min is -6 and max is 109 |
پارامترهای محلی در داخل توابع در دسترس هستند:
1 2 3 | func sample(number: Int) { print(number) } |
در مثال فوق آرگومان number به عنوان یک متغیر داخلی در تابع ()sample قابل دسترسی است.
حالا نحوه ی فراخوانی تابع فوق با ارسال پارامتر بصورت زیر است:
1 2 3 4 5 6 7 | func sample(number: Int) { print(number) } sample(number: 1) sample(number: 2) sample(number: 3) |
نحوه ی اجرای برنامه ی فوق با استفاده از playground بصورت زیر خواهد بود:
1 2 3 | 1 2 3 |
نام پارامترهای خارجی اجازه می دهد که در خارج از بدنه ی تابع و در هنگام فراخوانی تابع به نام پارامترها دسترسی داشته باشید:
1 2 3 4 5 6 7 8 9 10 | func pow(firstArg a: Int, secondArg b: Int) -> Int { var res = a for _ in 1..<b { res = res * a } print(res) return res } pow(firstArg:5, secondArg:3) |
نحوه ی اجرای برنامه ی فوق با استفاده از playground بصورت زیر خواهد بود:
1 | 125 |
هنگامی که قصد دارید مقادیر چندگانه به پارامترها اختصاص دهید می توانید ازساختار پارامترهای چندگانه استفاده کنید.
مثال :
1 2 3 4 5 6 7 8 9 | func vari<N>(members: N...){ for i in members { print(i) } } vari(members: 4,3,5) vari(members: 4.5, 3.1, 5.6) vari(members: "Swift 4", "Enumerations", "Closures") |
نحوه ی اجرای برنامه ی فوق با استفاده از playground بصورت زیر خواهد بود:
1 2 3 4 5 6 7 8 9 | 4 3 5 4.5 3.1 5.6 Swift 4 Enumerations Closures |
توابع به صورت پیش فرض پارامترها را به عنوان “ثابت” در نظر می گیرند.
اما کاربر می تواند پارامترها را به عنوان متغیر نیز تعریف کند.
قبلا گفته شد که برای تعریف ثابت از کلمه کلیدی ‘let’ و از ‘var’ برای تعریف متغیر استفاده می شود.
پارامترهای I/O مقادیر پارامترهای توابع را حفظ می کنند، و برای تعریف آن باید از کلمه کلیدی ‘inout’ استفاده کرد.
برای فراخوانی توابع با پارامترهای I/O باید قبل از نام پارامتر از کاراکتر ‘&’ استفاده کنید.
1 2 3 4 5 6 7 8 9 10 | func temp(a1: inout Int, b1: inout Int) { let t = a1 a1 = b1 b1 = t } var no = 2 var co = 10 temp(a1: &no, b1: &co) print("Swapped values are \(no), \(co)") |
نحوه ی اجرای برنامه ی فوق با استفاده از playground بصورت زیر خواهد بود:
1 | Swapped values are 10, 2 |
هر تابع با توجه به پارامترهای ورودی و تابع نتیجه خاصی را دنبال می کند.
1 2 3 | func inputs(no1: Int, no2: Int) -> Int { return no1/no2 } |
مثال:
1 2 3 4 5 6 | func inputs(no1: Int, no2: Int) -> Int { return no1/no2 } print(inputs(no1: 20, no2: 10)) print(inputs(no1: 36, no2: 6)) |
نحوه ی اجرای برنامه ی فوق با استفاده از playground بصورت زیر خواهد بود:
1 2 | 2 6 |
در اینجا تابع با دو آرگومان no1 و no2 به عنوان انواع داده های صحیح آغاز می شود و نوع بازگشت آن نیز به عنوان ‘int’ اعلام شده است:
1 2 3 | Func inputstr(name: String) -> String { return name } |
توابع ممکن است دارای انواع داده های void باشند و چنین توابعی چیزی را باز نمی گردانند.
مثال:
1 2 3 4 5 | func inputstr() { print("Swift 4 Functions") print("Types and its Usage") } inputstr() |
نحوه ی اجرای برنامه ی فوق با استفاده از playground بصورت زیر خواهد بود:
1 2 | Swift 4 Functions Types and its Usage |
توابع ابتدا با آرگومان های صحیح، اعشاری یا نوع رشته منتقل می شوند و پس از آن به عنوان تابع ثابت و یا متغیر به شکل زیر اعلام می شود:
1 | var addition: (Int, Int) -> Int = sum |
در اینجا sum یک نام تابع با متغیرهای عادی صحیح ‘a’ و ‘b’ است که اکنون به عنوان یک متغیر به عنوان افزودنی تابع اعلام شده است.
سپس تابع sum را داخل متغیر addition قرار داده و نتایج آن را در خروجی قرار می دهیم:
1 2 3 4 5 | func sum(a: Int, b: Int) -> Int { return a + b } var addition: (Int, Int) -> Int = sum print("Result: \(addition(40, 89))") |
نحوه ی اجرای برنامه ی فوق با استفاده از playground بصورت زیر خواهد بود:
1 | Result: 129 |
ما همچنین می توانیم تابع خود را به عنوان پارامترهای دیگر به یک تابع دیگر منتقل کنیم.
1 2 3 4 5 6 7 8 9 10 | func sum(a: Int, b: Int) -> Int { return a + b } var addition: (Int, Int) -> Int = sum print("Result: \(addition(40, 89))") func another(addition: (Int, Int) -> Int, a: Int, b: Int) { print("Result: \(addition(a, b))") } another(sum, 10, 20) |
نحوه ی اجرای برنامه ی فوق با استفاده از playground بصورت زیر خواهد بود:
1 2 | Result: 129 Result: 30 |
یک تابع توزیع شده امکان فراخوانی تابع درونی فراهم می کند.
1 2 3 4 5 6 7 8 9 10 11 | func calcDecrement(forDecrement total: Int) -> () -> Int { var overallDecrement = 0 func decrementer() -> Int { overallDecrement -= total return overallDecrement } return decrementer } let decrem = calcDecrement(forDecrement: 30) print(decrem()) |
نحوه ی اجرای برنامه ی فوق با استفاده از playground بصورت زیر خواهد بود:
1 | -30 |
توابع در تمام زبان های برنامه نویسی در کوتاه کردن کدها و حجم برنامه نقش بسیار مهمی را ایفا می کنند و همچنین باعث صرفه جویی در وقت نیز می شوند، از این رو در این بخش به مباحث کار با توابع در Swift پرداختیم.