Protocol Extension and Type Constraints
Introduction
Welcome to Lesson 2 of Generic Protocols. In Chapter 1, you’ve learned how to add constraints to generic functions with the example of LOL classes. Likewise, you may add constraints to a protocol extension so that the default implementation may only apply to specific classes and structs.
Problem
Limit the scope of Protocol Extension with where and Self
Generic Function - Review
Create a called LOL and create a function called addLOLClassOnly. The parameter of the function only works with value whose type is LOL.
1. class LOL {}
2. func addLOLClassOnly<T: LOL>(array: [T]) { }
3. addLOLClassOnly(array: [LOL()])
Design Protocol
Create a protocol called, GenericProtocol. Create SomeClass and SomeStruct of which conform to the protocol.
1. protocol GenericProtocol {
2. associatedtype myType
3. }
5. class SomeClass: GenericProtocol {
6. typealias myType = String
7. }
8. class SomeStruct: GenericProtocol {
9. typealias myType = Int
10. }
Design Protocol Extension
You may add constraints/conditions to extension by adding a where clause.
Create an extension that its default implementation applies to those whose associated type, myType is String
1. extension GenericProtocol where myType == String {
2. static func introduce() {
3. print("Yo, I'm Bob")
4. }
5. }
Classes, structs, and enums with myType as String contain the introduce() static method.
1. SomeClass.introduce() // "Yo I'm Bob"
2. SomeStruct.introduce() // Error
You may also add another where clause by adding ,. Let us apply the extension to SomeClass only.
1. extension GenericProtocol where myType == String, Self == SomeClass {
2. static func introduce() {
3. print("Yo, I'm Bob")
4. }
5. }
Notes:
Selfrefers to the class/struct/enum that conforms to the protocol.
Design Pre-Defined Associated Type
In the previous lesson, you’ve left associatedtype to be defined by the Self. Yet, you may pre-define the type within the protocol.
1. protocol FamilyProtocol {
2. associatedtype familyType = Int
3. var familyMembers: [familyType] { get set }
4. }
If you create a struct that conforms to FamilyProtocol, the required property, familyMembers has the type of [Int].
1. struct NumberFamily: FamilyProtocol {
2. var familyMembers: [Int] = [1, 3, 4]
3. }
Source Code
6002_Protocol Extension and Type Constraints.playground
Conclusion
Like generic constraints, you’ve learned how to limit the scope of protocol extensions by implementing where clauses. What a powerful tool. It prevents you from creating bloated objects filled with unnecessary methods and properties.
In the following lesson, you will learn how to override pre-defined associated type.
Note: Learn Swift with Bob is available on Udemy. If you wish to receive a discount link, you may sign up here.
