Swift throws/try/try?/try! の違いと安全な使い分け
生徒
「先生、Swiftのエラーハンドリングでthrowsとかtryとか、あとtry?やtry!って出てくるんですけど、違いがよく分からないんです。」
先生
「いい質問ですね。これらはSwiftでエラーをどう扱うかを決めるための大事な仕組みなんです。それぞれに使いどころがあるので、一つずつ分かりやすく見ていきましょう。」
生徒
「お願いします!間違ったらアプリが落ちるって聞いたので怖いです…」
先生
「確かに正しい使い分けを知らないと危ないですが、理解すれば安全に使えるようになりますよ。」
1. throwsとは?
throwsは「この関数はエラーを投げる(throwする)可能性があります」と宣言するためのキーワードです。宣言しておくことで、呼び出す側がエラーを意識して扱えるようになります。
例えば、ゼロで割り算をする可能性がある関数を作るときに使います。
enum DivisionError: Error {
case divideByZero
}
func divide(_ a: Int, _ b: Int) throws -> Int {
if b == 0 {
throw DivisionError.divideByZero
}
return a / b
}
このようにthrowsを付けることで、関数がエラーを外に伝えることを示しています。
2. tryの基本
tryは「エラーを投げる可能性のある関数を呼び出すとき」に必ず使うキーワードです。do-catchと組み合わせて安全に処理します。
do {
let result = try divide(10, 2)
print("結果: \(result)")
} catch {
print("エラーが発生しました: \(error)")
}
結果: 5
tryを使うと、もしエラーが起きてもcatchで受け止めることができ、アプリが強制終了しなくなります。
3. try? の特徴
try?は「エラーが出たらnilを返す」という便利な書き方です。失敗してもプログラムが止まらず、結果がオプショナル(値があるかないかを表す型)になります。
let safeResult = try? divide(10, 0)
print(safeResult) // nil
nil
例えば「ファイルが見つからなければ無視して続けたい」といったケースでは、このtry?がとても役立ちます。
4. try! の特徴と注意点
try!は「絶対にエラーが起きないと信じて実行する」ための書き方です。もし本当にエラーが発生した場合、アプリはクラッシュして強制終了します。
let forcedResult = try! divide(10, 2)
print(forcedResult)
5
このように正常な入力なら問題なく動きますが、危険性が高いので初心者はあまり使わない方がよいでしょう。
5. 安全な使い分け方
ここまで紹介したthrows、try、try?、try!の違いを整理すると、次のようになります。
throws:関数がエラーを投げる可能性があることを宣言する。try:エラーを投げる関数を呼び出すときに使い、do-catchで処理する。try?:失敗しても安全にnilを返す。軽いエラーチェックに便利。try!:失敗しないと確信しているときだけ使う。危険なので基本は避ける。
特に初心者の方は、まずtryとdo-catchで丁寧にエラーを処理する習慣をつけましょう。その後、状況に応じてtry?を取り入れると安全です。
6. 具体的な活用シーン
最後に、現実的なアプリ開発での使い分けをイメージしてみましょう。
- ネットワーク通信の失敗 →
tryとdo-catchでユーザーに「接続できませんでした」と表示する。 - ファイル読み込み → 失敗したら
nilでも問題ない場合はtry?を使う。 - アプリ内部で必ず成功すると分かっているテスト用処理 →
try!を限定的に使う。
このように「安全第一」で選ぶことが大切です。特にエラーハンドリングはアプリの信頼性やユーザー体験に直結するので、慎重に設計しましょう。