iOS Swift 5 新功能:Result Type

洋蔥胖
3 min readApr 11, 2019

--

Result Type 強制用一種安全的方法來處理函數調用返回的錯誤,而不需要拋出異常。盡管它通過異常,提供了一種自動化的機制來進行錯誤的傳遞和處理,但是Result Type 提供了一種手動機制,它有更強大的類型保障,並更適合異步錯誤處理。與 Option Type 相似,Result Type是一個 monad

Swift 5 中的 Result Type 作為enum 實作 有兩種情況:.success 和.failure。

你可以定義簡單的function,返回一個 Result和處理它的結果,如下:

此外,為了更方便和現有的function整合,Result Type 支持特定的初始化程序,它可以接受可能扔出的closure:

作為 monad,Result 實作已知的 map() 和 flatMap() 方法(以及理論上相同的 mapError() 和 flatMapError()):

  • map() (mapError()) 通過 closure 實現自動值轉換,但這只能在success(或failure)的情況下發生,否則 Result 就保持不變。
  • 當你想要使用closure 來轉換你的值(錯誤)的時候,flatMap() (flatMapError()) 很有用,因為 closure 會返回一個 Result 來處理轉換失敗的情況。在這種情況下,map() (mapError()) 會返回一個 <Result<Result<…>>。但有了 flatMap() (flatMapError()),你就能得到簡單的 Result。

Result Type 代表了對自 Swift 2 開始 Swift 中簡單的錯誤處理機制的 do、try、catch、throw 語法的改進,有多個原因。

首先,使用 Result Type 處理異步失敗變得更加自然。在 Swift 中典型的處理異步函數調用的模式是使用回調,如下例所示:

你可能很簡單就會發現,使用回調會破壞Swift 的異常目的,即自動傳遞和處理錯誤。反之,有了異步回調,錯誤就要當下馬上處理,因為當回調拋出異常的時候,錯誤再自動傳遞到call stack就已經太晚了。反之,當其他人 嘗試使用返回值的时候,Result 可能會儲存,晚點再進行處理。這種屬性稱為有延遲錯誤處理,不專屬於異步代碼,會大大簡化 Swift 的語法,如下所示:

上面的代碼在 Swift 5 中就會變成更容易閱讀的代碼片段,如下所示:

Result 的另外一個優勢,最後結果不是拿到想要的值,那就是會拿到錯誤,超清楚的二分法。

當使用回調的時候,我們可能得到四種類型的组合:完美結果、有值但有錯誤、沒有值但有錯誤、沒有值但也沒有錯誤。

最後,使用 Result Type 可以限制可能返回的error type。

在上面提供的第一个例子里,這個屬性幫助我們可以根據錯誤處理路徑完全枚舉可能的錯誤原因,比如说.failureReason1 和.failureReason2。反之,Swift 的函數抛出的錯誤並沒有指定類型,因此當處理 catch 區塊中的錯誤條件時,你只能知道錯誤 符合 Error 協議。

Swift 5 預計在 2019 年初發表,重點將是 給語言帶來 ABI 穩定性

--

--