A sequence on which normally-eager sequence operations are implemented lazily.
- Xcode 8.0+
- Swift Standard Library
Lazy sequences can be used to avoid needless storage allocation and computation, because they use an underlying sequence for storage and compute their elements on demand. For example,
doubled in this code sample is a sequence containing the values
Each time an element of the lazy sequence
doubled is accessed, the closure accesses and transforms an element of the underlying array.
Sequence operations that take closure arguments, such as
filter(_:), are normally eager: They use the closure immediately and return a new array. When you use the
lazy property, you give the standard library explicit permission to store the closure and the sequence in the result, and defer computation until it is needed.
Adding New Lazy Operations
To add a new lazy sequence operation, extend this protocol with a method that returns a lazy wrapper that itself conforms to
Lazy. For example, an eager
scan(_: method is defined as follows:
You can build a sequence type that lazily computes the elements in the result of a scan:
Finally, you can give all lazy sequences a lazy
With this type and extension method, you can call
.lazy on any sequence to create a lazily computed scan. The resulting
Lazy is itself lazy, too, so further sequence operations also defer computation.
The explicit permission to implement operations lazily applies only in contexts where the sequence is statically known to conform to
Lazy. In the following example, because the extension applies only to
Sequence, side-effects such as the accumulation of
result are never unexpectedly dropped or deferred:
Don’t actually use
map for this purpose, however, because it creates and discards the resulting array. Instead, use
reduce for summing operations, or
for or a
in loop for operations with side effects.