Result型とは
Result型とはSwift5から登場した機能で非同期でクロージャに値を渡す時やエラーハンドリングに役立ちます。
中身は以下のようになっています。
// Result型
public enum Result<Success, Failure: Error> {
case success(Success)
case failure(Failure)
}
Resultがsuccessの場合は付属値にSucess型の値が入り、failureの場合は付属値にFailure型の値が入ります。
肝は、SuccessとFailureにそれぞれ任意の型を指定するところです。
Result型を使うとき
クロージャに値を渡す時の例です。
ポケモンを例に見ていきます。
以下、Pokemon,PokeErrorを使うので一応載せておきます。
// Pokemonの定義
struct Pokemon {
var name: String?
var type: String?
var technique: String?
}
// pokeErrorの定義(Errorプロトコルに準拠しないとResult型のFailureに指定できません)
struct PokeError: Error {}
以下はクロージャを引数にとる関数と、受け取る側を実装した部分になります。
// completionに渡す値の型をPokemon型、PokeError型に指定
func getPokemon(completion: ((Result<Pokemon, PokeError>) -> Void)? = nil) {
// インスタンス化
let picatyuuu = Pokemon(name: "ピカチュウ", type: "でんき", technique: "十万ボルト")
let error = PokeError()
// ポケモンゲット
if isGot {
// Pokemon型の値を渡す
completion?(.success(picatyuuu))
} else {
// ポケモンゲットならず
// PokeError型の値を渡す
completion?(.failure(error))
}
}
// completionの結果を受け取る側
getPokemon { result in
switch result {
case .success(let picatyuuu):
// picatyuuuが使える
print("\(String(describing: picatyuuu.name))ゲットだぜ!")
case .failure(let error):
// errorが使える
print("\(error)だぜ!")
}
}
completionに渡す値の型はResult型で、Pokemon型またはPokeError型をcompletionに渡します。
この場合はピカチュウを捕まえたので、ピカチュウを付属値とするsuccessを渡してcompletionに渡して、呼び出し先でピカチュウを使って何かしら処理をしたいわけですね。
捕まえられなかった場合はerrorを付属値とするfailureを渡してあげます。
呼び出す側は受け取ったsuccess(hoge)またはfailure(fuga)の付属値hoge,fugaを使って処理します。(単にエラーかどうか知りたい場合は除く)
パターンマッチという技があるのでそれを使って付属値が取り出せます。
switch result {
case .success(let picatyuuu):
// picatyuuuが使える
print("\(String(describing: picatyuuu.name))ゲットだぜ!")
case .failure(let error):
// errorが使える
print("\(error)だぜ!")
}
この部分がパターンマッチを使ってるところです。
.success(let picatyuuu)でpicatyuuuが使えます。errorも然り。
最後に
ご指摘あればお願いします。