With the recent deprecation and future removal of the post and pre
increment and decrement operators in Swift, I recently updated the code
in Catchlines, my Swift project, ready for these changes. Most of the work
was very simple and involved swapping n++
with n += 1
or similar. I
only had one case where I was actually relying on the post increment
behaviour.
I had some code similar to the following from early on in the project. I
had a type Bar
in this case, and a type for managing a collection of
Bar
instances, Foo
.
struct Bar {}
struct Foo {
let data: [Bar]
}
I had wanted to treat Foo
as a sequence so I'd added the following
code (I was a bit greener with Swift when I wrote this, but I'm
including it to demonstrate the only real use case of post increment I
had).
extension Foo: SequenceType {
struct BarGenerator: GeneratorType {
var data: [Bar]
var idx: Int = 0
init(data d: [Bar]) {
data = d
}
mutating func next() -> Bar? {
if idx < data.count {
return data[idx++]
}
return nil
}
}
func generate() -> BarGenerator {
return BarGenerator(data: data)
}
}
Here I wrote a small indexing GeneratorType
for Foo
that took a copy
of the data and kept track of an index for how far through the sequence
we were. When checking what to return next I made sure I wasn't
out of bounds, and then returned the item in my stored data at the
current index, and post incremented the index immediately after using it.
I can re-write that next
method to guard
against the out of bounds
error and return nil
. I can then use a temporary variable to store the
index I want to return and increment idx
.
mutating func next() -> Bar? {
guard idx < data.count else {
return nil
}
let val = idx
idx += 1
return data[val]
}
This doesn't seem as elegant, but probably reads much better to someone who isn't aware of what post and pre increment do.
What I really needed to do
I now know that I really shouldn't even have a BarGenerator
, I should
just be using the IndexingGenerator
provided by Array
, but you live
and learn.
extension Foo: SequenceType {
func generate() -> IndexingGenerator<[Bar]> {
return data.generate()
}
}