با عرض سلام و وقت بخیر خدمت کاربران سایت پی وی لرن . و کاربرانی که دوره کامل آموزش Swift را دنبال می کنند. قابلیت استفاده از کلاس، ساختار یا نوع شما رنده ی موجود را می توان با کمک extension یا افزونه ها در Swift اضافه کرد. قابلیت تایپ را نیز می توان با استفاده از افزونه ها اضافه کرد، اما عملکرد overriding نمی توان با استفاده از افزونه ها اعمال کرد. قابلیت extension در Swift به شما اجازه می دهد تا موارد ذکر شده را در قالب یک بلوک {} با یک نوع مشخص شده تعریف کرده و در طول برنامه از آن استفاده کنید. در ادامه ی این مباحث برای آشنایی با نحوه ی کار با افزونه ها در Swift با ما همراه باشید.
در ادامه ی این آموزش به سینتکس و چند نمونه از روند کار با افزونه ها در Swift آشنا خواهید شد.
قابلیت های گسترش Swift
افزونه ها با کلمه کلیدی ‘extension’ تعریف می شوند:
1 2 3 | extension SomeType { // new functionality can be added here } |
نوع موجود نیز می تواند به افزونه ها اضافه شود تا به عنوان یک استاندارد پروتکل و سینتکس آن مشابه کلاس ها یا ساختارها باشد:
1 2 3 | extension SomeType: SomeProtocol, AnotherProtocol { // protocol requirements is described here } |
محاسبه ی خصوصیات ‘instance’ و ‘type’ را می توان به کمک قابلیت extension در Swift اضافه کرد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | extension Int { var add: Int {return self + 100 } var sub: Int { return self - 10 } var mul: Int { return self * 10 } var div: Int { return self / 5 } } let addition = 3.add print("Addition is \(addition)") let subtraction = 120.sub print("Subtraction is \(subtraction)") let multiplication = 39.mul print("Multiplication is \(multiplication)") let division = 55.div print("Division is \(division)") let mix = 30.add + 34.sub print("Mixed Type is \(mix)") |
نتیجه ی کامپایل و اجرای کد فوق به صورت زیر خواهد بود:
1 2 3 4 5 | Addition is 103 Subtraction is 110 Multiplication is 390 Division is 11 Mixed Type is 154 |
Swift 4 انعطاف پذیری لازم را برای افزودن initializer های یک نوع موجود توسط افزونه ها را ارائه می کند.
کاربر می تواند انواع سفارشی خود را برای گسترش نوعی که قبلا تعریف شده است اضافه کند.
افزونه ها در Swift فقط از ()init پشتیبانی می کند و ()deinit توسط افزونه ها پشتیبانی نمی شود.
مثال :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | struct sum { var num1 = 100, num2 = 200 } struct diff { var no1 = 200, no2 = 100 } struct mult { var a = sum() var b = diff() } let calc = mult() print ("Inside mult block \(calc.a.num1, calc.a.num2)") print("Inside mult block \(calc.b.no1, calc.b.no2)") let memcalc = mult(a: sum(num1: 300, num2: 500),b: diff(no1: 300, no2: 100)) print("Inside mult block \(memcalc.a.num1, memcalc.a.num2)") print("Inside mult block \(memcalc.b.no1, memcalc.b.no2)") extension mult { init(x: sum, y: diff) { let X = x.num1 + x.num2 let Y = y.no1 + y.no2 } } let a = sum(num1: 100, num2: 200) print("Inside Sum Block:\( a.num1, a.num2)") let b = diff(no1: 200, no2: 100) print("Inside Diff Block: \(b.no1, b.no2)") |
نتیجه ی کامپایل و اجرای کد فوق به صورت زیر خواهد بود:
1 2 3 4 5 6 | Inside mult block (100, 200) Inside mult block (200, 100) Inside mult block (300, 500) Inside mult block (300, 100) Inside Sum Block:(100, 200) Inside Diff Block: (200, 100) |
متدهای نوع جدید و انواع متدها را می توان با کمک برنامه های افزونه ها به زیر کلاس اضافه کرد.
مثال :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | extension Int { func topics(summation: () -> ()) { for _ in 0..<self { summation() } } } 4.topics(summation: { print("Inside Extensions Block") }) 3.topics(summation: { print("Inside Type Casting Block") }) |
نتیجه ی کامپایل و اجرای کد فوق به صورت زیر خواهد بود:
1 2 3 4 5 6 7 | Inside Extensions Block Inside Extensions Block Inside Extensions Block Inside Extensions Block Inside Type Casting Block Inside Type Casting Block Inside Type Casting Block |
تابع ()topic آرگومان را از نوع ‘(summation: () → ())
‘ می گیرد و برای نشان دادن تابع، هیچ آرگومانی را نمی پذیرد و هیچ مقداری را نمی دهد.
برای فراخوانی چند مرتبه ی این تابع ، برای بلوک مقداردهی اولیه شده و با متد ()topic مقداردهی اولیه انجام می شود.
متدهای نمونه می توانند در زمان تعریف افزونه ها تغیر کنند.
ساختارها و شمارنده ها که خود یا خصوصیات خود را تغییر می دهد باید متد نمونه را به عنوان جهش، همانند متدهای جهش از یک پیاده سازی اصلی، علامت گذاری کند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | extension Double { mutating func square() { let pi = 3.1415 self = pi * self * self } } var Trial1 = 3.3 Trial1.square() print("Area of circle is: \(Trial1)") var Trial2 = 5.8 Trial2.square() print("Area of circle is: \(Trial2)") var Trial3 = 120.3 Trial3.square() print("Area of circle is: \(Trial3)") |
نتیجه ی کامپایل و اجرای کد فوق به صورت زیر خواهد بود:
1 2 3 | Area of circle is: 34.210935 Area of circle is: 105.68006 Area of circle is: 45464.070735 |
اضافه کردن زیرساخت های جدید به موارد اعلام شده قبل نیز، ممکن است با پسوند امکان پذیر باشد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | extension Int { subscript(var multtable: Int) -> Int { var no1 = 1 while multtable > 0 { no1 *= 10 --multtable } return (self / no1) % 10 } } print(12[0]) print(7869[1]) print(786543[2]) |
نتیجه ی کامپایل و اجرای کد فوق به صورت زیر خواهد بود:
1 2 3 | 2 6 5 |
انواع تو در تو برای کلاس ها ، ساختار و انواع شمارنده ها می تواند به کمک قابلیت extension در Swift اضافه شوند :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | extension Int { enum calc { case add case sub case mult case div case anything } var print: calc { switch self { case 0: return .add case 1: return .sub case 2: return .mult case 3: return .div default: return .anything } } } func result(numb: [Int]) { for i in numb { switch i.print { case .add: print(" 10 ") case .sub: print(" 20 ") case .mult: print(" 30 ") case .div: print(" 40 ") default: print(" 50 ") } } } result(numb: [0, 1, 2, 3, 4, 7]) |
نتیجه ی کامپایل و اجرای کد فوق به صورت زیر خواهد بود:
1 2 3 4 5 6 | 10 20 30 40 50 50 |
در زبان Swift 4 ، قابلیت استفاده از کلاس، ساختار یا نوع شمارنده های موجود را می توان با کمک extension یا افزونه ها در Swift اضافه کرد. با این ساختار می توانید موارد موجود در برنامه در extension تعریف کرده و در طول برنامه بر اساس نوع از آن ها استفاده کنید.