Swiftで従来のthrow
~catch
では書きづらい場面も多々あるので、
RustのResult
型を参考にした、エラーハンドルを取り入れてみました。
やること
SwiftでRustのResult
型のような、直和型の返り値を使ったエラーハンドルを実現する。
実装
enum
を使って直和型であることを表現します。
Genericsとassociated valueで、結果(型T
)かエラー(型E
)のどちらかの値を持つ状態を表現します。
case
Rustに倣って、ok
とerror
の2つのcaseを持ちます。
enum Result<T, E> { case ok(T) case error(E) }
switch
文で、ok
の場合とerror
の場合の処理を記述することができます。
メソッド
ok
, error
の場合のみ処理を書きたい時のために、Optional
で返すメソッドを用意します。
func ok() -> T? { switch self { case .ok(let result): return result case .error: return nil } } func error() -> E? { switch self { case .ok: return nil case .error(let error): return error } }
その他
例えば、map
などの実装はこのようになります。
func map<U>(_ transform: ((T) -> U)) -> Result<U, E> { switch self { case .ok(let result): return .ok(transform(result)) as Result<U, E> case .error(let error): return .error(error) as Result<U, E> } }
使い方
switchで使う
typealias Res = Result<Int, String> let someResult: Res = .ok(1) switch someResult { case .ok(let result): print(result) case .error(let error): print(error) }
Optionalで使う
if let result = someResult.ok() { print(result) }
サンプル
ここにあります。