The Swift GeneratorType reference says about the next method:
next()Advance to the next element and return it, or nil if no next element exists.
And then in the discussion, it says
Requires:
next()has not been applied to a copy ofselfsince the copy was made, and no preceding call toself.next()has returnednil. Specific implementations of this protocol are encouraged to respond to violations of this requirement by callingpreconditionFailure("...").
If the Generator is for an Optional type, then it is possible for it to reach a nil value before reaching the end of the sequence. How does Swift know that it has not reached the end in this case?
It's important to note that whatever type a generator is generating, it wraps that type in an optional.
The GeneratorType protocol declares an associated type which it calls Element and a method, next(), whose return type is of type Element?. Whatever Element is, next() wraps it in an optional (and remember, optional is just an enum).
So a generator generating optionals wraps those optionals in another optional layer.
Consider the following:
let array: [Int?] = [1, 2, nil, 4, nil, nil, 7, 8, nil, nil, 11]
This is an array of optional integers.
So if we call generate() on this array, it will give us something that returns type Optional<Optional<Int>> or Int?? from the next() method.

The first two calls to next will give us values (1, then 2). The third looks like it returns nil:

But effectively this is just misleading information. Realistically, the third return is actually this: Optional.Some(nil)
We can see that there are more values to generate by looking at this while loop, which is terminated by the real nil that is generated after 11:

All of the nil values we see print are actually Optional.Some(nil), and when the next() call finally returns Optional.None, the loop terminates.
What we're looking at here is the difference between the following three values possible values:
let optionalSomeValue: Int?? = 3
let optionalSomeNil: Int?? = Optional.Some(nil)
let optionalReallyNil: Int?? = nil
Note that the second line could also be written as:
let optionalSomeNil: Int?? = Optional.Some(Optional.None)
At the end of the day, we have to keep in mind that optional is just a generic enum:
enum Optional<T> {
case Some(T)
case None
}
There is no restriction on what T can be, which means it can itself be an optional, and it could be an optional with case None.
In Swift, the nil keyword is just a convenient shortcut for Optional<T>.None and the ? syntax for declaring optionals is likewise a convenient shortcut for Optional<T>.Some. Consider that the following two lines are equivalent in every manner except the variable name:
let foo = Optional<Int>.None
let bar: Int? = nil

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With