2017-08-14 41 views
4

私は連続したtry文を使いたいと思います。エラーが返された場合は次のエラーに進みます。それ以外の場合は値を返します。 以下のコードは正常に動作しているようですが、ピラミッドをキャッチする大きな入れ子になります。 Swift 3.0でもっとスマートで良い方法がありますか?ネストされたdo catch swift 3.0

do { 
    return try firstThing() 
} catch { 
    do { 
     return try secondThing() 
    } catch { 
     return try thirdThing() 
    } 
} 
+2

をあなたの 'do'内のすべてのあなたの' try'ステートメントを実行し、あなたの 'catch'の中で例外をキャッチします。それらを入れ子にする必要はありません。 – Pancho

+0

firstThingが失敗した場合にOPだけを実行したい場合は@Panchoを実行し、secondThingが失敗した場合はthirdThingを実行します。 – Abizern

+0

ありがとう@Pancho、しかし、私は値(またはエラー)任意のコードを返すので、最初のリターンは実行されません。 – Mymodo

答えて

9

これらの関数呼び出しからスローされた実際のエラーが を必要とされていない場合、あなたはオプションで、 とチェーンはnil-合体演算子??との通話に結果を変換するtry?を使用することができます。例えば

すべてが失敗した場合、最後のメソッドからエラーがスローされなければならない場合
if let result = (try? firstThing()) ?? (try? secondThing()) ?? (try? thirdThing()) { 
    return result 
} else { 
    // everything failed ... 
} 

または、すべてのための 使用try?が、最後のメソッド呼び出し:

return (try? firstThing()) ?? (try? secondThing()) ?? (try thirdThing()) 
+0

私は最後のエラーが必要なので、これは仕事をする必要があります。ありがとう。 – Mymodo

7

マーティンの場合は答えはあなたの味のためにあまりにも簡潔です。あなたは個々のキャッチブロックに行くことができます。

do { 
    return try firstThing() 
} catch {} 

do { 
    return try secondThing() 
} catch {} 

do { 
    return try thirdThing() 
} catch {} 

return defaultThing() 

各投げ出し機能の結果がすぐに返されるので、ネスティングは必要ありません。

+0

Cool、これはオプションに変換せずに解決します。 Nikolaiに感謝します。 – Mymodo

+2

シンプルでクリアな(既にアップvoted)。 –

3

これを行う別の方法は、すべての投げ込み関数を引数としてとる関数を書くことです。正常に実行された最初のもの、またはnilを返します。

func first<T>(_ values: (() throws -> T)...) -> T? { 
    return values.lazy.flatMap({ (throwingFunc) -> T? in 
     return try? throwingFunc() 
    }).first 
} 

怠惰それが最初の一致が見つかるまで値がのみ呼び出されることを保証します。このようにすると、多くのケースを非常に迅速に追加することができます。

あなたはこの

return first(firstThing, secondThing, thirdThing) ?? "Default" 

のような機能を使用することができますまた、私は遊び場でこれをテストするために使用されるコードが含ま:

enum ThingError: Error { 
    case zero 
} 

func firstThing() throws -> String { 
    print("0") 
    throw ThingError.zero 
    return "0" 
} 

func secondThing() throws -> String { 
    print("1") 
    return "1" 
} 

func thirdThing() throws -> String { 
    print("2") 
    return "B" 
} 

func first<T>(_ values: (() throws -> T)...) -> T? { 
    return values.lazy.flatMap({ (throwingFunc) -> T? in 
     return try? throwingFunc() 
    }).first 
} 

func tryThings() -> String { 
    return first(firstThing, secondThing, thirdThing) ?? "Default" 
} 

tryThings() // prints "0" and "1" 
関連する問題