Learn how to create generic protocol and override associated type
original source :Ā https://blog.bobthedeveloper.io/generic-protocols-with-associated-type-7e2b6e079ee2
ģ°øź³ ė“ģ©
protocol Sequence<T> { Ā Ā func generate() -> Generator<T> }
ģģ ź°ģ ķģģ¼ė” generic protocolģ ė§ė¤ģ ģģ§ ģģź¹ ģź°ķ ģ ģģ§ė§ swiftģģė ė§ė¤ģ ģė¤. ėģ associatedtypeģ ģ“ģ©ķ“ģ¼ ķė¤.Ā
Introduction
Youāve started learning Protocols and youāve got addicted to it. One day, you heard some words like associated type and type eraser. It seems rough and wild. I feel you. So, I wrote this tutorial for you. Letās get started.
Goals
There are two objectives. First, learn how to create a generic protocol with associatedtype. Second, use where clauses for type constraints similar to that of generics.
Prerequisites
I consider this tutorial as somewhat intermediate-advanced. So, I expect you to be familiar with the topics below.
Intro to Generics, Intro to Protocol Oriented Programming, Closure, Typealias.
If you are not comfortable with the topics above, you might find Learn Swift with Bob useful.
p.s Iām going to be around a while. I plan to cover server-side Swift, RxSwift, Test driven, and all the good stuff. š
The Number One Rules
The Swift Programming Language is considered as type-safe. It means, the type must be defined before compiled.
Review
Before we dive into generic protocols, you should be familiar with the following code below.
struct GenericStruct<T> { var property: T? }
I could either explicitly state the type of T or let Swift infer based on the value.
let explictStruct = GenericStruct<Bool>() // T is Bool
let implicitStruct = GenericStruct(property: "Bob") // T is String
Keep in mind of the principle that every type must be defined.
Normal Protocol
First, to appreciate generic protocols, letās look into your/my past. Letās create a protocol that requires you to add property whose type is String.
Design Protocol
protocol NormalProtocol { var property: String { get set } }
Design Class and Conform
class NormalClass: NormalProtocol { var property: String = "Bob" }
Sounds good. However, NormalProtocol forces NormalClass to work with String. But, what if you want property to be Int or Bool?
Itās time to introduce Protocol Associated Types. š (I should have a thug-life meme)
Introducing Protocol Associated Types
In generic protocols, to create something like <T> in generics, you need to add associatedtype.
protocol GenericProtocol { associatedtype myType var anyProperty: myType { get set } }
Associated type = type alias + generics
Now, anything that conforms to GenericProtocol must implement anyProperty. However, the type is not defined. Therefore, the class or struct that conforms to the protocol must define it either implicitly or explicitly.
First, letās create a class SomeClass that conforms to GenericProtocol. We must define myType. Well, there are two ways to define as stated above.
Define Associated Type Implicitly
You may define myType based on the value associated with anyProperty.
class SomeClass: GenericProtocol { var anyProperty: myType = "Bob" }
Now, myType has been defined as String based on āBobā. However, you can let Swift do more guessing as shown below.
class SomeClass: GenericProtocol { var anyProperty = "Bob" // myType is "String" }
Is everything okay with you? If so far so good, you can show me some love through ā¤ļø.
Define Associated Type Explicitly
Well, you may also define the associated type, myType by calling typealias. What? Letās take a look.
class SomeClass: GenericProtocol { typealias myType = String var anyProperty: myType = "Bob" }
If you want to define the associatedtype a.k.a myType, you may use typealias. Of course, it is not necessary since you may define myTypeimplicitly as weāve seen.
So far, youāve defined myType as String. Letās create a struct that conforms to GenericProtocol but myType is Int instead.
struct SomeStruct: GenericProtocol { var anyProperty = 1996 }
Youāve implicitly stated that myType is Int based on the value of 1996.
If you hear Protocol Associated Types (PATs), it just means generic protocols.
Protocol Extension and Type Constraints
As you already know, Protocol extension is amazing because it provides default implementations without having to define required methods and properties. Letās review.
Design Extension
extension GenericProtocol { static func introduce() { Ā print("I'm Bob") } }
Anything that adopts GenericProtocol now contains this magic.
SomeClass.introduce() // I'm Bob SomeStruct.introduce() // I'm Bob
But all of a sudden, you only want myType as String to have the introduce()method. How do you go about?


















