`Result {}`という初期化が見慣れなかったので紹介
はじめに
iOSエンジニアをしている、Nao-RandD です 🚴🏻♂️
Swiftを実装する中で、Result
を利用することは多いかと思いますが、Result {}
のようなクロージャーを用いた初期化がされている時にピンとこなかったため、その備忘録も兼ねた記事になります。
以下のようにして、Resultをクロージャーで初期化することができます。(雑なサンプルでごめんなさい 🙉)
func hoge(isSuccess: Bool) -> Result<String, MySomeError> {
Result {
if isSuccess {
return "Success"
} else {
throw MySomeError.receiveNotSuccess
}
}
}
"こんな書き方できたのか"、となったのでここから紹介していきます。
Result型とは?
特に説明するまでもないかも知れませんので、”知っているよー”という方は読み飛ばしてください 🤗
Resultは、Swift 5.0 で導入された、成功または失敗のいずれかを表すことのできる型になります。
成功、失敗をそれぞれassociated value
として独自に定義することができます。
- success(T): 処理が成功した場合の結果を保持します。
- failure(Error): 処理が失敗した場合のエラーを保持します。
成功した場合にはInt
で、失敗した時にはMyValueError
としてResultを定義するならResult<Int, MyValueError>
のような感じですね。
今回のクロージャーを用いた初期化
それでは、クロージャーを用いたResultを扱う方法に進んでいきましょう。
クロージャーでの初期化は、catchingという() throws -> Success
のクロージャーを渡しています。
簡単な例が良いかと思いますので、引数でnumerator
(分子)とdenominator
(分母)を受け取り、除算を行うメソッドを例に考えてみましょう。
クロージャーを用いない場合には以下のようなコードになるかと思います。
enum MathError: Error {
case divisionByZero
}
func divide(_ numerator: Int, by denominator: Int) -> Result<Int, MathError> {
if denominator == 0 {
// 0除算は許容しないためMathError.divisionByZeroを返す
return .failure(MathError.divisionByZero)
}
return .success(numerator / denominator)
}
// 使用例
let result = divide(10, by: 2)
switch result {
case .success(let quotient):
print("Result: \(quotient)") // 分母が2の場合、出力は "Result: 5"
case .failure(let error):
print("Error: \(error)")
}
これをクロージャーでのResult初期化を利用して以下のように書くことができます。
func divide(_ numerator: Int, by denominator: Int) -> Result<Int, MathError> {
Result {
if denominator == 0 {
throw MathError.divisionByZero
}
return numerator / denominator
}
}
// 使用例
// ・・・(上と同じ)
Resultのクロージャーでの初期化を利用すると、
- 成功:.successの
associated value
でreturn - 失敗:.failureの
associated value
でthrow
で表現することができます。
成功時にはreturnし、失敗時にはthrowして、通常のthrowsメソッドのように記述することができるわけですね。
まとめ
”使わないと損”というものではないと思いますが、.success, .failureで書かずに、return, throwで扱えるため実装時にはこちらの方が使いやすいなと思ったりしました🤔
今回はResultのクロージャーでの初期化に出会って、”ナニコレ👀”となったので自身の備忘録がてら記事にさせていただきました。
Discussion