Swift Collection 中的 lazy 做用

惰性求值

惰性求值常見於函數式編程中,也有人把惰性求值翻譯成延遲求值(Lazy Evaluation)。它的目的是要最小化計算機要作的工做。在使用惰性求值的時候,表達式不在它被綁定到變量以後就當即求值,而是在該值被取用的時候求值。 惰性求值的優勢很明顯:程序員

  • 計算只有在真正須要的時候纔會執行 這個特性就給代碼優化提供了更多的可能性。有些運算可能在某個條件分支下才會被用到。某些計算可能和後面的計算相抵消,能夠優化運算的方式。寫一段僞代碼大概以下:
let a = 100
let b = 1000
let c = a/b
print(c*b) 
複製代碼

最後求值的時候發現表達式是a/b*b,因此最後輸出的時候的值就爲a,省掉了除b,乘b的運算。編程

  • 無窮的數據結構 由於在沒被使用的時候只是一個表達式,在程序中真正使用某幾項具體數據的時候纔會去計算,因此惰性求值能夠聲明一個無窮的序列。 下面的代碼先定義了一個從 1 開始的奇數序列:
var nums = sequence(first: 1, next: { num in
    return num + 2
})

// 這個時候才進行真正的計算
for n in nums.prefix(5) {
    print(n)
}
複製代碼

Swift 中的 lazy

Swift 的編程範式雖然有函數式編程,可是 swift 和純函數式編程的語言如 haskell 仍是有一些差距。Swift 中集合操做默認的求值策略是 eager,就是及早求值。當表達式賦值給一個變量時計算就進行了。 爲了支持惰性求值,在 collection 經過 lazy 屬性能夠獲取到一個惰性的集合。swift

// a huge collection
let giant = 0..<Int.max
// lazily map it: no work is done yet
let mapped = giant.lazy.map { $0 * 2 }
// sum the first few elements
let sum = mapped.prefix(10).reduce(0, +)
// sum == 90
複製代碼

上面的代碼中,mapped 賦值時計算並無發生,由於 lazy 返回的 LazyCollecion 上的 map 操做是惰性的。bash

取捨

惰性求值的缺點就和異步同樣,寫代碼的時候不能顯示的看出執行順序。 在有些場景是須要及時求值的。好比下面的代碼在惰性求值的體系下第一行不須要在第二行前執行:數據結構

System.out.println("Please enter your name: ");
System.in.readLine();
複製代碼

所以一個編程語言也不能只支持惰性求值。只是在 swift 中,蘋果認爲大部分的時候及早求值就能知足場景,須要經過顯式的 lazy 獲取惰性集合。固然也可能在 swift 前期特性中,函數式的一些特性不是最核心的需求,期待後期的 swift 特性吧。app


引用異步


歡迎關注個人微博:@沒故事的卓同窗編程語言

掘金博客地址:juejin.im/user/5624c8…函數式編程

若是想與我有更密切的交流也能夠加入個人小密圈:程序員生存指南函數

相關文章
相關標籤/搜索