😇

try, try!, try? from Swift

2024/07/04に公開

Tips💡

Swiftのコードを書いてると、tryに、!, ? がついていたりする。そもそも私、tryの使い方すらわかってないです(−_−;)

昔、プログラミングスクールで勉強したけど、忘れた😇

思い出そう

try keyword?

error を発生させる可能性のある処理の実行
throws keywordが指定された処理を呼び出すには、それらの処理の呼び出しの前に、try keywordを追加して、try func 関数名(引数) {} と記述する。
try keywordを用いた処理の呼び出しは、throw 文と同様に、do catch 文の do 節と throws keyword が指定された処理の内部で使用できます。

以下のコードだと、Intの引数を渡して、値が1未満だと例外を投げる処理です。

import Foundation

// Swift try文の書き方のパターン
// 1. do-catch文
enum MyError: Error {
    case error1
    case error2
}

func myFunction(of int: Int ) throws -> Int {
    // 1未満だと例外を投げる
    if int < 1 {
        throw MyError.error1
    }
    // エラーで場合は、引数の値を返す
    return int
}

do {
    // try文の中でエラーが発生すると、catch文に飛ぶ
    let result = try myFunction(of: 0)
    print(result)
} catch MyError.error1 {
    print("error1")
} catch {
    print("error")
}

try!

throws keywordが記述された処理であっても、特定の場面では絶対にエラーが発生しない場合でもエラー処理を記述したくないケースもあったりする。
さ場合は、try! エラーを無視することができます。catch, do, throws keywordが指定された処理の中でなくても使用できます。

// 2. try!文
enum MyError2: Error {
    case error1
    case error2
}

// エラーが発生しないので、try!文を使う
func myFunction2(of int: Int ) throws -> Int {
    return int
}

// 必ず値を返すので、エラーが発生しない。なので、try!文を使う
let result2 = try! myFunction2(of: 1)
print(result2)// 1

try! はSwiftの安全性を損ねる機能に見えると技術書に書かれていました。しかし「すべてのエラーに対処」というのは面倒で現実的ではないです。「明示的なエラーの無視」が目的だそうで、エラーを無視できるが、無視したことを明らかに、したいということで使います。! ですが、安全ではないという処理を意味していることを伝えてます。

try?

throws keywordが指定された処理でもエラーの処理が不要な場合もあります。このようなケースでは、try? を使用。try? をつけて、throws を呼び出すと、do catch 文を省略でき、関数の戻り値が、Optional<Wrapped> 型になる。

// 3. try?文
enum MyError3: Error {
    case error1
    case error2
}

// エラーが発生しないので、try?文を使う
func myFunction3(of int: Int ) throws -> Int {
    guard int > 1 else {
        throw MyError3.error1
    }
    return int * 2
}

// エラーが発生しないので、try?文を使う
let result3 = try? myFunction3(of: 2)
print(result3)// Optional(4)

感想

使うときは基本は、throwsと組み合わせますね。エラーが発生しないのが保証されているコードには、try!をつけて、try?をつけると、エラーの処理が不要な場合で、do catchを省略して、戻り値が、Optionalになります。
少しでも参考なれば良いかなと思い記事を書きました。

Discussion