Iterator Design Pattern in Swift Universe
An unnoticed behavioral pattern in detail.
--
Iterator is one of the design patterns which often stay unnoticed by programmers because its implementation details are usually already embedded in the programming language’s standard library. However, it’s also one of behavioral patterns described in a Gang of Four (GoF) classical book “Design Patterns: Elements of Reusable Object-Oriented Software”. Its comprehension won’t never be redundant and might be helpful.
Iterator is a way to provide serial access to all elements of a composite object (usually, a container type, such as array and set).
Built-In Features
Create an array:
let numbersArray = [0, 1, 2]
…and iterate it with a loop:
for number in numbersArray {
print(number)
}
…are very common things to do, especially for modern programming languages, such as Swift. Nevertheless, this feature is backed by code which implements the Iterator design pattern.
In Swift, a type is required to conform toSequence
protocol for being able to be iterated by a for
loop. Among other things, this protocol requires to have associated type Iterator
(which must conform to IteratorProtocol
) and to implement the factory method makeIterator()
(which returns specific iterator for this type):
protocol Sequence {
associatedtype Iterator : IteratorProtocol
func makeIterator() -> Self.Iterator
// Another requirements go here...
}
IteratorProtocol
contains the only method — next()
, which returns following object in sequence:
protocol IteratorProtocol {
associatedtype Element
mutating func next() -> Self.Element?
}
(It might feel like a lot of complicated code but it’s not, really. We shall see it in a while.)
For example, Array
confroms to Sequence
(not directly though, but through protocol inheritance chaining: MutableCollection
inherits from Collection
which inherits from…