Swift & Objective-C

SwiftのthrowsとResult:失敗理由を失わない入力処理

try?でnilにまとめられる二種類の失敗を、typed throwsとResultで区別し、getで成功値の取得とエラー再送出を確認します。

読了 3 分
SwiftのthrowsとResult:失敗理由を失わない入力処理のカバー画像

失敗理由によって次の行動が変わるなら、try?で消さずthrowsやResultで保持します。throwsは呼び出しの流れでエラーを伝え、Resultは成功・失敗を値として保存して後で処理できます。

仕組みと設計の判断基準

ParseErrorは数値でない入力と負数を区別します。throws(ParseError)は送出するエラー型を明示し、do-catchで適切な応答を選べます。try?は両方をnilへまとめるため、復旧方針が異なる場合には情報が足りません。 一次資料

再現コード

cat、-1、0、42を同じパーサーへ渡します。二つの失敗がtry?ではnilになることを確認し、各結果をResult<Int, ParseError>へ保存します。typed doでcatchの型を明示し、getで成功値を取り出すか失敗を再送出します。

この独立したサンプルは2026-10-23に、arm64 macOS向けのApple Swift 6.4をSwift 6言語モードで実行しました。ネットワーク接続や追加パッケージは不要です。

Swiftファイル全体をダウンロード

ダウンロード先のフォルダーで実行してください。検証条件を満たさない場合はpreconditionで停止します。検証が削除されるため、-Ouncheckedは使用しないでください。

swift -swift-version 6 swift-error-handling-throws-result.swift
enum ParseError: Error, Equatable { case notInteger, negative }
func parse(_ raw: String) throws(ParseError) -> Int {
    guard let value = Int(raw) else { throw .notInteger }
    guard value >= 0 else { throw .negative }
    return value
}

precondition((try? parse("cat")) == nil && (try? parse("-1")) == nil)
let results: [Result<Int, ParseError>] = ["cat", "-1", "0", "42"].map { raw in
    do throws(ParseError) { return .success(try parse(raw)) }
    catch { return .failure(error) }
}
precondition(results == [.failure(.notInteger), .failure(.negative), .success(0), .success(42)])
do {
    _ = try results[1].get()
    preconditionFailure("failure was lost")
} catch ParseError.negative {}
let recovered = try results[3].get()
precondition(recovered == 42)
print("try?-failures=nil,nil result=notInteger,negative,0,42 get-error=negative")

実行結果と読み取り方

try?-failures=nil,nil result=notInteger,negative,0,42 get-error=negative

配列にはnotInteger、negative、0、42が別々に残ります。失敗結果のgetはnegativeを再送出し、成功結果からは42が得られます。ネットワークやファイルI/Oなしで、エラー情報の保持を検証しています。

適用範囲と注意点

throwsですべての失敗を捕捉できるわけではありません。強制アンラップやprecondition違反のトラップは契約の外です。try!の失敗も通常の復旧経路ではありません。この実験は同期パースのみで、非同期キャンセルや再試行、ファイルエラーは未検証です。

次に確認すること

エラーは呼び出し側が異なる行動を取る単位で分けます。単純な不在ならOptional、理由の伝達ならthrows、保存や集計ならResultを検討します。UI表示とログは実際の原因を保持した境界でつなぐとよいでしょう。

関連する実験

出典と確認基準

  • The Swift Programming Language: Error HandlingSwift.org · 公式ドキュメント · 確認日 2026年10月23日根拠: 実装の契約と説明の根拠です。出力は、この記事に掲載した実験で別途確認しました。