在舊SWIFT世界的封閉(2.0我相信)的功能,我有以下的Y組合子實現問題傳遞閉包需要一個逃避關閉,以接受該類型
func Y<T, R>(f: (T -> R) -> (T -> R)) -> (T -> R) {
return { (t: T) -> R in
return f(self.Y(f))(t)
}
}
我會打電話在Y梳子別處創建一個遞歸的關閉,像這樣:
let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
let repeatClosure = self.Y {
(f:() ->()) -> (() ->()) in
return {
if self.responses_received != responses_expected {
dispatch_after(delayTime, dispatch_get_main_queue()) {
// Resend
NSNotificationCenter.defaultCenter().
postNotificationName(sendData,
object: nil, userInfo: dataToSend)
f()
}
} else {
print("Completed!")
self.responses_received = 0
}
}
}
repeatClosure()
的想法是,作爲「送出數據」的通知觀察員收到了他的回覆,他會發送通知,要求類涵蓋我Y-組合子和重複關閉。一旦「送出數據」的通知觀察員的所有實例都收到了他們的數據,
self.responses_received == responses_expected
將是真實的,並且我們不會()再次調用F。
現在,我的問題是,轉換爲雨燕3.0已經迫使我明確聲明「F」的類型爲@escaping,Y上的,像這樣的定義:
func Y<T, R>(_ f: @escaping ((T) -> R) -> ((T) -> R)) -> ((T) -> R) {
return { (t: T) -> R in
return f(self.Y(f))(t)
}
}
,隨後轉化我重複關閉有相同的類型。這很好,我理解@escaping和@noescape之間的區別以及爲什麼我的代碼需要它。然而,試圖建立時,我得到一個編譯錯誤,關於不匹配的類型:
Cannot convert value of type '(@escaping() ->()) -> (() ->())'
to expected argument type '(() ->()) -> (() ->())'
我創建了一個簡單的實例關閉只是爲了測試與給出了同樣的錯誤:
let innerClosure = { (f: @escaping()->()) -> (()->()) in
return {}
}
let repeatClosure = self.Y(innerClosure)
而以下是沒有問題的:
let innerClosure = { (f:()->()) -> (()->()) in
return {}
}
let repeatClosure = self.Y(innerClosure)
我從fixit得到了強制轉換類型的建議,沒有使用@escaping標記。這個編譯,但它感覺錯了,我沒有真正測試,演員是否會在運行時真正工作。
我在這裏錯過了什麼?
阿哈,這就是它,非常感謝你! – agreendev