When we create a protocol we can declare some types as generics, this allows to use a different type on each adoption.
Let's look at an example of a protocol where, after defining our Associated Type Item
, we use it to define the type of an array and the parameter of a method.
protocol ListProtocol {
associatedtype Item
var items: [Item] { get set }
func append(item: Item)
}
At this point, Item
is not tied to any specific type, as this will be defined by the class that implements ListProtocol
.
To demonstrate, we've created the object Person
and the class Party
that implements ListProtocol
using Person
as the type.
struct Person {
let name: String
}
class Party: ListProtocol {
var items: [Person] = []
func append(item: Person) {
items.append(item)
}
}
In this case, ListProtocol
infers that Item
is of type Person
. The advantage of an Associated Type is that it allows us to use a different variable type.
struct Passenger {
let identifier: Int
let name: String
}
class Flight: ListProtocol {
var items: [Passenger] = []
func append(item: Passenger) {
items.append(item)
}
}
We can only use one type per Associated Type and context, meaning we must use the same type in both the array and the method. However, we can define multiple Associated Types.
Adding constraints to our Associated Types
It's possible to require that our Associated Types implements a protocol. This allows us to add certain functionalities knowing which protocol types we're dealing with.
For instance, let's say we want to add the function append(item:)
in an extension, but only append items that don't already exist in our array, this means that items must be Equatable
in order to compare them using contains()
function.
To edit items
from our extension, we've marked our function as mutating
.
protocol ListProtocol {
associatedtype Item: Equatable
var items: [Item] { get set }
mutating func append(item: Item)
}
extension ListProtocol {
mutating func append(item: Item) {
if !items.contains(item) {
items.append(item)
}
}
}
Now, when we create an object, the variable type we use must implement the Equatable
protocol, such as String
.
class Party: ListProtocol {
var items: [String] = []
}
var myParty = Party()
myParty.append(item: "Pablo")
Or Int
.
class NumberList: ListProtocol {
var items: [Int] = []
}
var myNumberList = NumberList()
myNumberList.append(item: 10)
Be the first to comment