我得到這個從一本書,這個代碼在didSet方法使用,我爲什麼時,你可以編寫調用兩個函數放緩()或函數加速功能,這將是有益的困惑()??這基本上是聲明一個「可變函數」和「設置它等於它自己的定義」,然後返回一個「函數」? (如我錯了請糾正我)。爲什麼需要使用一個變量,並將其設置爲等於定義時,我可以創建一個函數?那有什麼用處?
回答
當你開始學習函數文字,取得和返回其他函數的函數,以及包含函數的變量時,所有新的模式都會打開。這是編程中最強大的工具之一。
您的描述不完全正確。這不是「設定它等於自己的定義」。它將函數看作是值,就像整數,布爾值或結構一樣。當你把一個函數看作一個值時,你可以組合函數,就像你結合其他值一樣。這是非常強大的。
讓我們考慮基於你只是一個很簡單的例子:
var speed = 0
func speedup() { speed++ }
func slowdown() { speed-- }
var changeSpeed = speedup
speed // 0
changeSpeed()
speed // 1
OK很大。但正如你所說,我們可以設定一個布爾或什麼,只是做了我們想做的事情。但是,讓我們把它進一步:
func twice(f:() -> Void) -> (() -> Void) { return { f(); f() } }
這是一個函數,函數返回一個新的函數,它兩倍的第一個。再讀一遍,並考慮一下。這是一個函數,它可以使用函數,並且可以使增加。我們不在乎這個功能是什麼。我們可以加倍任何東西
因此,讓我們加倍我們改變功能:
changeSpeed = twice(changeSpeed)
changeSpeed()
speed // 3
我們沒有修改speedup
處理這個問題。 twice
不關心我們是否通過speedup
或slowdown
或我們未來可能發明的其他功能。我們有很多種方法可以擴展這些代碼,而無需重寫任何原始代碼。我們可以訪問twice
等更高階的函數。這些功能可以實現或返回其他功能,而且它們非常強大。在雨燕,它們包括像map
和filter
,這一切都依賴於創造文字的功能,並將它們分配到事物的能力。
讓我們再走一步。不要擔心這個代碼中的所有想法,只是它允許我們做什麼。
import Darwin
var speed = 0
func speedup() { speed++ }
func slowdown() { speed-- }
var changeSpeed:() throws ->() = speedup
// This funny syntax lets us more easily create a function that takes a
// function and retries it some number of times. It's called "currying".
// But the point is that calling `retry` will create a new function that
// retries the given function.
func retry(n: Int)(_ f:() throws -> Void)() rethrows {
for _ in 1..<n {
do {
try f()
return
} catch {
print("It failed. Let's try it again!")
}
}
// One last try. If it fails, so we do we
try f()
}
struct FailedError : ErrorType {}
// Similarly, `maybe` takes a function and might choose not to run it
func maybe(p: Float)(_ f:() throws ->())() throws {
if Float(arc4random())/Float(INT32_MAX) < p {
try f()
} else {
throw FailedError()
}
}
// With that, we can create a function called "lotsOfTries" that tries
// other functions 10 times. Yes, we're creating a function with `let`.
let lotsOfTries = retry(10)
// And we can create a function that fails other functions most of the time.
let badChance = maybe(0.15)
// And then we can glue them all together without knowing how they work internally.
changeSpeed = lotsOfTries(badChance(speedup))
do {
try changeSpeed()
print(speed)
} catch {
print("Couldn't do it, sorry")
}
所以這些是你可以建立的功能,一旦你真的擁抱這種編碼。在我自己的代碼,我使用類似retry
功能,因爲「重試若干次,但僅適用於特定類型的錯誤,並沒有太多的時間」是獨立的什麼東西被試一個非常複雜的問題。我創建了將調用記錄到其他函數的函數,這對於一致的日誌記錄來說非常方便。我有一個執行身份驗證,然後換行不進行代理那套其他 HTTP請求處理程序....這是怎樣構圖功能的工作原理其他 HTTP請求處理程序,它可以真正改變你怎麼寫的HTTP請求處理程序程式。
而且,在最簡單的情況下,這可以讓我們做回調。所以,時不時地出現......
哇!我剛剛登錄並閱讀了您的答案,您是我的朋友,擁有出色的才能!我對這個問題有點清楚,但對我來說它仍然有點新,但是你剛寫的內容令人難以置信,我很佩服!我們可以聯繫,也可以一起在一個項目上工作嗎? – Ali
- 1. 這個Swift函數聲明中的額外變量是什麼
- 2. 什麼是變量聲明的dart函數類型語法?
- 3. 在函數聲明中定義變量類型Ruby
- 4. 爲什麼要在類的構造函數中聲明變量?
- 5. 函數調用前面的類型聲明是什麼意思
- 6. 在swift中聲明變量
- 7. 在swift中聲明這些變量時有什麼區別!或()
- 8. 爲什麼不能在F#中的函數中聲明類型?
- 9. 爲什麼要在註釋中聲明PHP變量類型?
- 10. 什麼`... |類型聲明中的b - > c是什麼意思?
- 11. 爲什麼變量在Javascript中的函數之前聲明
- 12. 在類的函數聲明後,「default」是什麼意思?
- 13. 在golang中聲明一個具有任意返回類型的函數類型
- 14. 「聲明中的重複數據類型」是什麼意思?
- 15. Django - 爲什麼模型類中聲明的變量靜態
- 16. 爲什麼Java變量聲明中的類型不同?
- 17. 如何在Swift中的函數外使用變量聲明?
- 18. 爲什麼只有一些函數使用在函數外聲明的變量?
- 19. 爲什麼使用||在變量函數聲明中?
- 20. 爲什麼要在定義函數的過程中聲明變量?
- 21. Swift中的靜態字典類型變量聲明?
- 22. 在Java中聲明默認構造函數有什麼意義嗎?
- 23. 在Swift類或結構中聲明爲靜態的變量會發生什麼?
- 24. 什麼是Ruby的類似Python的變量,未在類定義中聲明?
- 25. 爲什麼GenSet聲明具有不變類型參數?
- 26. 從函數聲明中使用類型變量
- 27. 變量聲明和數據類型
- 28. 這是什麼類型的聲明?一個函數?類?
- 29. 在類中聲明時無法訪問變量。在函數中聲明時工作。爲什麼?
- 30. 如果聲明瞭變量,swift變量類型在downcast後不會改變?
簡而言之,將函數視爲一級成員允許函數被存儲,作爲參數傳遞(高階函數)等等。雖然它們的使用可能不明顯從您提供的示例中,查看https://en.wikipedia.org/wiki/First-class_function#Higher-order_functions:_passing_functions_as_arguments – Roshan