با عرض سلام و وقت بخیر خدمت کاربران سایت پی وی لرن . و کاربرانی که دوره کامل آموزش Swift را دنبال می کنند. زبان Swift 4 ویژگی ‘Generic’ را برای نوشتن انواع توابع انعطاف پذیر و قابل استفاده ی مجدد را ارائه می دهد. Generic ها برای جلوگیری از تکثیر و استفاده از انتزاع استفاده می شود. کتابخانه های استاندارد Swift 4 با کد generic ساخته شده است. نوع های ‘Arrays’ و ‘Dictionary’ در Swift 4 متعلق به مجموعه های generic است. برای آشنایی بیشتر با طرز کار با ویژگی Generic در Swift در ادامه ی مباحث با ما همراه باشید.
در این آموزش شما با سینتکس و طرز کار با ویژگی Generic در Swift آشنا خواهید شد.
با کمک آرایه ها و دیکشنری ها آرایه هایی برای نگهداری مقادیر ‘Int’ و ‘String’ یا هر نوع مقدار دیگری تعریف می شوند.
مثال :
1 2 3 4 5 6 7 8 9 10 11 12 | func exchange(a: inout Int, b: inout Int) { let temp = a a = b b = temp } var numb1 = 100 var numb2 = 200 print("Before Swapping values are: \(numb1) and \(numb2)") exchange(a: &numb1, b: &numb2) print("After Swapping values are: \(numb1) and \(numb2)") |
نتیجه ی کامپایل و اجرای کد فوق:
1 2 | Before Swapping values are: 100 and 200 After Swapping values are: 200 and 100 |
توابع generic می تواند برای دسترسی به هر نوع داده نظیر ‘Int’ یا ‘String’ استفاده شود.
مثال :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | func exchange<T>(a: inout T, b: inout T) { let temp = a a = b b = temp } var numb1 = 100 var numb2 = 200 print("Before Swapping Int values are: \(numb1) and \(numb2)") exchange(a: &numb1, b: &numb2) print("After Swapping Int values are: \(numb1) and \(numb2)") var str1 = "Generics" var str2 = "Functions" print("Before Swapping String values are: \(str1) and \(str2)") exchange(a: &str1, b: &str2) print("After Swapping String values are: \(str1) and \(str2)") |
نتیجه ی کامپایل و اجرای کد فوق:
1 2 3 4 | Before Swapping Int values are: 100 and 200 After Swapping Int values are: 200 and 100 Before Swapping String values are: Generics and Functions After Swapping String values are: Functions and Generics |
تابع ()exchange برای مقادیر swap استفاده می شود که در برنامه ی فوق توصیف شده است.
همچنین <T> به عنوان نوع پارامتر استفاده می شود.
در اولین مرتبه تابع ()exchange برای بازگرداندن مقادیر ‘Int’ فراخوانی می شود.
دومین فراخوانی تابع ()exchange نیز مقادیر ‘String’ را باز می گرداند.
انواع پارامترهای چندگانه می تواند داخل براکت {} تعریف شده و با استفاده از کاما از هم تفکیک شوند.
پارامترهای نوع توسط کاربر نامگذاری شده تا نوع پارامتری که نگه می دارند را بدانیم.
با این وجود پارامترهای نوع همانند آرایه ها و دیکشنری ها می تواند با key و مقدار نامگذاری شود که برای شناسایی آنها به نوع “دیکشنری” کاربرد دارد.
مثال :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | struct TOS<T> { var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } } var tos = TOS<String>() tos.push(item: "Swift 4") print(tos.items) tos.push(item: "Generics") print(tos.items) tos.push(item: "Type Parameters") print(tos.items) tos.push(item: "Naming Type Parameters") print(tos.items) let deletetos = tos.pop() |
نتیجه ی کامپایل و اجرای کد فوق:
1 2 3 4 | [Swift 4] [Swift 4, Generics] [Swift 4, Generics, Type Parameters] [Swift 4, Generics, Type Parameters, Naming Type Parameters] |
گسترش خصوصیت پشته برای دانستن بالای آیتم با کلمه کلیدی ‘extension’ گنجانده شده است.
مثال :
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 | struct TOS<T> { var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } } var tos = TOS<String>() tos.push(item: "Swift 4") print(tos.items) tos.push(item: "Generics") print(tos.items) tos.push(item: "Type Parameters") print(tos.items) tos.push(item: "Naming Type Parameters") print(tos.items) extension TOS { var first: T? { return items.isEmpty ? nil : items[items.count - 1] } } if let first = tos.first { print("The top item on the stack is \(first).") } |
نتیجه ی کامپایل و اجرای کد فوق:
1 2 3 4 5 | ["Swift 4"] ["Swift 4", "Generics"] ["Swift 4", "Generics", "Type Parameters"] ["Swift 4", "Generics", "Type Parameters", "Naming Type Parameters"] The top item on the stack is Naming Type Parameters. |
Swift 4 اجازه می دهد که type constraints برای مشخص کردن اینکه آیا پارامتر نوع از یک کلاس خاص به ارث می برد یا برای اطمینان از استاندارد انطباق پروتکل استفاده شود.
مثال :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | func exchange<T>(a: inout T, b: inout T) { let temp = a a = b b = temp } var numb1 = 100 var numb2 = 200 print("Before Swapping Int values are: \(numb1) and \(numb2)") exchange(a: &numb1, b: &numb2) print("After Swapping Int values are: \(numb1) and \(numb2)") var str1 = "Generics" var str2 = "Functions" print("Before Swapping String values are: \(str1) and \(str2)") exchange(a: &str1, b: &str2) print("After Swapping String values are: \(str1) and \(str2)") |
نتیجه ی کامپایل و اجرای کد فوق:
1 2 3 4 | Before Swapping Int values are: 100 and 200 After Swapping Int values are: 200 and 100 Before Swapping String values are: Generics and Functions After Swapping String values are: Functions and Generics |
Swift 4 اجازه می دهد انواع مرتب شده باید در تعریف پروتکل با کلمه کلیدی ‘associatedtype’ اعلام شود.
مثال :
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 | protocol Container { associatedtype ItemType mutating func append(item: ItemType) var count: Int { get } subscript(i: Int) -> ItemType { get } } struct TOS<T>: Container { // original Stack<T> implementation var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } // conformance to the Container protocol mutating func append(item: T) { self.push(item: item) } var count: Int { return items.count } subscript(i: Int) -> T { return items[i] } } var tos = TOS<String>() tos.push(item: "Swift 4") print(tos.items) tos.push(item: "Generics") print(tos.items) tos.push(item: "Type Parameters") print(tos.items) tos.push(item: "Naming Type Parameters") print(tos.items) |
نتیجه ی کامپایل و اجرای کد فوق:
1 2 3 4 | [Swift 4] [Swift 4, Generics] [Swift 4, Generics, Type Parameters] [Swift 4, Generics, Type Parameters, Naming Type Parameters] |
محدودیت های نوع کاربر را قادر می سازد تا الزامات مربوط به پارامترهای نوع مرتبط با یک تابع یا نوع عمومی را تعریف کند.
برای تعریف الزامات مربوط به نوع قوانین ‘where’ به عنوان بخشی از لیست پارامتر نوع اعلام شده است.
کلمه ی کلیدی ‘where’ بلافاصله بعد از لیست پارامترهای نوع به دنبال محدودیت های مربوط به انواع، بین نوع و انواع مرتبط قرار می گیرد.
مثال :
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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | protocol Container { associatedtype ItemType mutating func append(item: ItemType) var count: Int { get } subscript(i: Int) -> ItemType { get } } struct Stack<T>: Container { // original Stack<T> implementation var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } // conformance to the Container protocol mutating func append(item: T) { self.push(item: item) } var count: Int { return items.count } subscript(i: Int) -> T { return items[i] } } func allItemsMatch< C1: Container, C2: Container where C1.ItemType == C2.ItemType, C1.ItemType: Equatable> (someContainer: C1, anotherContainer: C2) -> Bool { // check that both containers contain the same number of items if someContainer.count != anotherContainer.count { return false } // check each pair of items to see if they are equivalent for i in 0..<someContainer.count { if someContainer[i] != anotherContainer[i] { return false } } // all items match, so return true return true } var tos = Stack<String>() tos.push(item: "Swift 4") print(tos.items) tos.push(item: "Generics") print(tos.items) tos.push(item: "Where Clause") print(tos.items) var eos = ["Swift 4", "Generics", "Where Clause"] print(eos) |
نتیجه ی کامپایل و اجرای کد فوق:
1 2 3 4 | [Swift 4] [Swift 4, Generics] [Swift 4, Generics, Where Clause] [Swift 4, Generics, Where Clause] |
ویژگی Generic در Swift را برای نوشتن انواع توابع انعطاف پذیر و قابل استفاده ی مجدد را ارائه می دهد. Generic ها برای جلوگیری از تکثیر و استفاده از انتزاع استفاده می شود.