函数式编程中有惰性求值的概念,即一次计算在真正需要时才执行,尽可能推迟求解表达式。

假如我们有一个数组,我们对每个元素作element*2的map操作,获取其中某一个元素,我们会如下代码处理:

let array = [1, 2, 4, 5, 3, 7]
let element = array.map{ $0 * 2 }[3]
print(element)

这个计算对每个元素都*2,最后我们只取了其中一个值,也就是说在这个场景中另外5次计算是无意义的。

这时使用惰性求值就可以避免这算浪费。我们知道Swift中有个lazy关键字,如果用来修饰属性之类的,可以实现属性的惰性求值。同样,Swift扩展了LazySequenceProtocol协议,提供了一个lazy属性,用于处理map,filter等操作的惰性求值,定义如下代码所示:

/// Avoid creating multiple layers of `LazySequence` wrapper.
/// Anything conforming to `LazySequenceProtocol` is already lazy.
extension LazySequenceProtocol {

    /// Identical to `self`.
    public var lazy: Self { get }
}

所以,上面这个例子如果要实现惰性求值,则可以如下代码处理:

let array = [1, 2, 4, 5, 3, 7]
let element = array.lazy.map{ $0 * 2 }[3]
print(element)

我们在Playground中可以看到,整个计算中实际只执行了一次*2操作。