やって、やって!してみますか?違いは何ですか、それぞれをいつ使用するのですか?


172

スウィフト2.0、Appleがエラーを(行う-のtry-catch)を処理するための新しい方法を導入しました。そして数日前にベータ6でさらに新しいキーワードが導入されました(try?)。また、私が使用できることを知っていましたtry!。3つのキーワードの違いは何ですか、それぞれをいつ使用するのですか?

回答:


316

Swift 5.1用に更新

次のスロー関数を想定します。

enum ThrowableError: Error {

    case badError(howBad: Int)
}

func doSomething(everythingIsFine: Bool = false) throws -> String {

  if everythingIsFine {
      return "Everything is ok"
  } else {
      throw ThrowableError.badError(howBad: 4)
  }
}

試す

スローする可能性のある関数を呼び出す場合、2つのオプションがあります。

do-catchブロック内で呼び出しを囲むことにより、エラー処理の責任を負うことができます。

do {
    let result = try doSomething()
}
catch ThrowableError.badError(let howBad) {
    // Here you know about the error
    // Feel free to handle or to re-throw

    // 1. Handle
    print("Bad Error (How Bad Level: \(howBad)")

    // 2. Re-throw
    throw ThrowableError.badError(howBad: howBad)
}

または、関数を呼び出して、呼び出しチェーン内の次の呼び出し元にエラー渡します

func doSomeOtherThing() throws -> Void {    
    // Not within a do-catch block.
    // Any errors will be re-thrown to callers.
    let result = try doSomething()
}

やってみよう!

内部にnilがある暗黙的にアンラップされたオプションにアクセスしようとするとどうなりますか?はい、本当です、アプリはクラッシュします!同じことは試してみてください!基本的にはエラーチェーンを無視し、「実行または終了」の状況を宣言します。呼び出された関数がエラーをスローしなかった場合、すべてがうまくいきます。しかし、失敗してエラーがスローされた場合、アプリケーションは単にクラッシュします。

let result = try! doSomething() // if an error was thrown, CRASH!

やってみる?

Xcode 7ベータ6で導入された新しいキーワード。成功した値をラップ解除するオプション返し、 nilを返すことでエラーをキャッチします。

if let result = try? doSomething() {
    // doSomething succeeded, and result is unwrapped.
} else {
    // Ouch, doSomething() threw an error.
}

または、ガードを使用できます。

guard let result = try? doSomething() else {
    // Ouch, doSomething() threw an error.
}
// doSomething succeeded, and result is unwrapped.

最後try?に、nilに変換されるため、発生したエラーを破棄することに注意してください。試してみる?失敗した理由ではなく、成功と失敗に焦点を合わせているとき。

結合演算子の使用??

合体演算子を使用できますか?試しに?失敗した場合にデフォルト値を提供するには:

let result = (try? doSomething()) ?? "Default Value"
print(result) // Default Value

2番目のコードサンプル(let result = try doSomething() // Not within a do-catch block)は、として宣言されているメソッド内から呼び出されますthrowsよね?では、doSomething()失敗した場合、外側のメソッドも(順番に)失敗しますか?
Nicolas Miari

古いスレッドと私以外はすべて今日(Swift 4、Xcode 9.1)試してみましたか?結果を自動アンラップしません。手動でアンラップするための通常のオプションのままにしておきます。これがSwift 2/3以降に変更されたかどうかはわかりませんが、次のドキュメントに従っています:developer.apple.com/library/content/documentation/Swift/…エラーのオプション値への変換を参照)。try btwの素晴らしい説明。
the_dude_abides 2017年

1
Swift 4で試してみませんか?私のプロジェクトの「try」式内で発生するスロー関数へのno呼び出しは削除されません。
aznelite89 2017

7
また、使用することができますtry???、それはあなたが1行にデフォルト値を定義できますので、:let something:String = (try? whateverIfItThrows()) ?? "Your default value here"
itMaxence
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.