Result型エラー処理
Result型エラー処理の特徴
- 戻り値として「成功」か「失敗」のどちらかであることが保証される
- 失敗の場合に失敗の詳細情報を提供できる
- 非同期処理のレスポンスに使用できる
1. Result型の定義
Result
enum Result<T, Error> {
case success(T)
case failed(Error)
}
2. エラー型の定義
エラー
enum LoginError {
case invalid
case notFound
case unknown
}
3. 成功(結果)
成功
struct Account {
let id: Int
let token: String
}
4. 処理定義
func login(id: Int) -> Result<Account, LoginError> {
if id < 0 || 100000 < id { return .failed(.invalid) }
let accounts = [
Account(id: 111, token: "abc111"),
Account(id: 222, token: "xyz222")
]
for account in accounts {
if id == account.id {
return .success(account)
}
}
return .failed(.notFound)
}
5. 実行
let result = login(id: 111)
switch result {
case let .success(account):
print(account.token)
case let .failed(error):
print(error)
}
応用
// Result型定義
enum Result<T, Error> {
case success(T)
case failed(Error)
}
// エラー定義
enum LoginError: String {
case invalid = "不正な値"
case notFound = "見つからない"
case unknown = "不明なエラー"
}
// データ定義
struct Account {
let id: Int
let token: String
}
// 処理定義
func login(id: Int) -> Result<Account, LoginError> {
if id < 0 || 100000 < id { return .failed(.invalid) }
let accounts = [
Account(id: 111, token: "abc111"),
Account(id: 222, token: "xyz222")
]
for account in accounts {
if id == account.id {
return .success(account)
}
}
return .failed(.notFound)
}
// レスポンスハンドリング定義
func response<T, E>(result: Result<T, E>, failed: ((_ error: E) -> Void)? = nil, success: ((_ data: T) -> Void)? = nil) {
switch result {
case let .success(data):
if let completion = success {
completion(data)
}
case let .failed(e):
if let completion = failed {
completion(e)
}
}
}
// 実行
resuponse(result: login(id: 123), failed: { error in print(error.rawValue) }) { data in
print(data.token)
}