這編譯:
let badger = get_closure()
func get_closure() -> (Int) -> Void {
return { (x: Int) -> Void in
print(x)
if x > 4 {
return
} else {
badger(x 1)
}
}
}
badger(1)
這與回圈參考錯誤無關:
let badger = get_closure()
let get_closure = { () -> (Int) -> Void in
return { (x: Int) -> Void in
print(x)
if x > 4 {
return
} else {
badger(x 1)
}
}
}
badger(1)
為什么?我認為func語法只是第二種更明確的語法的糖。
uj5u.com熱心網友回復:
第一個有效的事實是編譯器中長期存在的錯誤/怪癖,而不是預期的功能。它基于編譯器無法檢測到的未定義行為。您可以通過將您的作業代碼包裝在一個函式中來證明它是頂級宣告的一個怪癖,并看到它與您的第二個示例非常相似地失敗:
func f() {
let badger = get_closure()
func get_closure() -> (Int) -> Void { // ERROR: Closure captures 'badger' before it is declared
return { (x: Int) -> Void in
print(x)
if x > 4 {
return
} else {
badger(x 1)
}
}
}
badger(1)
}
像這樣的頂級全域宣告的關鍵特性badger是它們是惰性求值的,因此賦值實際上發生在函式宣告之后。在您的第二個示例中,兩個變數都是惰性的,因此順序又回來了。但是,正如鏈接的論壇帖子中所討論的那樣,依賴這個事實是危險的。
在探索微妙的 Swift 行為時,我總是建議構建一個命令列應用程式并將您的測驗代碼放在一個函式中,以消除 Playgrounds 和頂級可執行代碼的怪異之處。(在這種情況下,游樂場并不相關,但它出現了很多。)
uj5u.com熱心網友回復:
很難理解應該在哪里使用這種方法,但如果你真的想要,那么試試這個:
let get_closure: (Int) -> Void = { x in
print(x)
if x > 4 {
return
} else {
badger(x 1)
}
}
let badger = get_closure
badger(1)
因變數的初始化順序通常很重要。如果在閉包之后賦值,就不會報錯:
let get_closure = { () -> (Int) -> Void in
return { (x: Int) -> Void in
print(x)
if x > 4 {
return
} else {
badger(x 1)
}
}
}
let badger = get_closure()
badger(1)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/520652.html
標籤:迅速递归编译器错误关闭
