SwiftでResultとthrowsを使い分ける目安
Swiftで失敗する処理を書くとき、throws にするか Result にするか迷うことがあります。
呼び出してすぐ処理するなら throws、結果を値として保持したいなら Result、くらいで見ると整理しやすいです。
throwsを使う場面
enum LoadError: Error {
case notFound
}
func loadName() throws -> String {
throw LoadError.notFound
}
呼び出し側では do-catch で扱います。
do {
let name = try loadName()
print(name)
} catch {
print(error)
}
普通の関数呼び出しとして書けるので、失敗をその場で処理するなら throws が読みやすいです。
Swiftのエラーハンドリングは公式のLanguage Guideにもまとまっています。
https://docs.swift.org/swift-book/documentation/the-swift-programming-language/errorhandling/
Resultを使う場面
Result は成功か失敗かを値として持てます。
let result: Result<String, Error> = .success("Makonote")
状態として保持したい場合に向いています。
enum ViewState {
case idle
case loaded(Result<String, Error>)
}
非同期処理の完了結果を一度プロパティに保持したい場合などは、Result の方が扱いやすいことがあります。
async throws
非同期処理なら async throws にできます。
func fetchName() async throws -> String {
"Makonote"
}
呼び出し側では try await します。
let name = try await fetchName()
async/await の基本は Swiftでasync/awaitとTaskを使うときに最初に見ること に分けています。
まとめ
throws と Result は、失敗をどう扱いたいかで分けます。
- その場で呼び出して処理するなら
throws - 非同期なら
async throws - 結果を状態として保持するなら
Result - UI状態に持つなら
Resultが合うこともある
まずは throws で書き、値として持ち回りたくなったら Result を考える流れで十分です。


