2017-04-09 62 views
3

據我瞭解,rethrows實質上從一個單一的聲明/定義創建兩個函數,就像這樣:保存重新拋出功能作爲非投擲封閉

func f(_ c:() throws -> Void) rethrows { try c()} 

// has the same effect as declaring two seperate functions, with the same name: 

func g(_ c:() throws -> Void) throws { try c() } 
func g(_ c:() -> Void) { c() } 

如果我有一個重新拋出功能,如f,有沒有辦法將它保存爲「非拋出」形式的閉包?可以想像,像這樣:

let x: (() -> Void) -> Void = f 
// invalid conversion from throwing function of type '(() throws -> Void) throws ->()' to non-throwing function type '(() -> Void) -> Void' 

x{ print("test") } // "try" not necessary, because x can't throw 
+1

是否'令x:(() - >無效) - >虛空= {F($ 0 )}'算作解決方案?這不是封閉,而是封裝。 –

+0

@MartinR我想是的,是的。我發現奇怪的是,沒有(我知道)允許這個任務的類型關係 – Alexander

+0

您可能有興趣知道編譯器實際上只會爲'rethrows'函數創建一個重載 - 一個'throws' 。如果將它應用於不會拋出的閉包,編譯器會簡單地減少函數返回錯誤的可能性。因此我懷疑沒有簡單的方法來獲得非投擲表單 - 封閉包裝可能是最好的解決方案。 – Hamish

回答

3

直到有人想出了一個更好的解決方案:使用包裝

func f(_ c:() throws -> Void) rethrows { try c()} 

let x: (() -> Void) -> Void = { f($0) } 
+0

我會延遲接受這個答案,直到有更多的人有機會看到問題 – Alexander

+0

@Alexander:當然! - 順便說一句,一個簡單的賦值'let x = f'使'x'成爲「只拋出」閉包。顯然只有函數可以重新拋出而不是關閉聲明。 –

+0

是的,我注意到,這很奇怪。 – Alexander