2016-01-06 9 views
14

私は、スウィフトでこの愚かな振る舞いに遭遇しましたが、オプションの強制アンラッピングは伝播しません。スウィフトフォースアンラップ例外が伝播しない

使用しようとすると:ドキュメントから

!存在しない任意の値にアクセスすると、ランタイムエラーが発生します。使用する前にオプションにnil以外の値が含まれていることを必ず確認してください。その値を強制的にアンラップします。

再現するために:

func foo(bar:String?) throws{ 
    print(bar!); 
} 

そして

try foo(nil); 

をこれは私には論理的または一貫していないようだと、私はこの主題上の任意のドキュメントを見つけることができません。

これは仕様です。 documentationから

+2

'throw '(これはエラーがそのような関数内から伝播する原因となります)でエラーを投げても、' nil'を強制解除したときと同じことです。私はどこかで 'assert()'として実装されていると読んでいると思います。 –

+0

それはそれを説明するだろうが、それはひどい。たぶん引数がありますが、例外をサポートする言語では一貫性がないようです。 – Greg

+7

@Greg:ニコラスが正しいです。 try/catchはSwift * errors *(Throwされる 'ErrorType'に準拠した値)を処理することに注意してください。それは、ランタイムエラーや例外とはまったく関係ありません。 (ドキュメントでは、スロー/トライ/キャッチと関連して「例外」という単語はなく、「エラー処理」のみです。) –

答えて

10

エラー処理の処理

エラーに応答して、プログラムで エラー条件から回復するプロセスです。 Swiftは実行時に回復可能な エラーをスロー、キャッチ、伝播および操作するためのファーストクラスサポート を提供します。

...

表し、投げるエラースウィフトで

は、エラーが ErrorTypeプロトコルに準拠型の値で表されます。この空のプロトコルは、エラー処理のためにタイプが であることを示します。

(注意:ErrorTypeはスウィフト3にErrorに名前が変更されました)

のでtry/catchとあなたがthrow nはスウィフトエラーErrorTypeプロトコルに準拠型の値)を扱います。 これは、ランタイムエラーと実行時例外 (およびFoundationライブラリのNSExceptionとは無関係です)とはまったく関係ありません。中

エラー処理のスウィフトのドキュメントでも唯一の例外で、 単語「例外」を使用しないこと(強調鉱山)に注意(!):

NOTE

エラー処理Swiftのは、try、catch、throwキーワードを使用して、 の言語で例外処理に似ています。 Objective-Cエラー Swiftでの処理では、多くの言語での例外処理とは異なり、計算コストがかかる というプロセスが呼び出されます。したがって、throwステートメントのパフォーマンス の特性は、 returnステートメントの特性に匹敵します。

あるoptionalsのアンラップnilしないthrow(伝播することができる)と tryで扱うことができない スウィフトエラー。などnilに対してチェックあなたは オプションの結合、オプションのチェーンのような周知の技術を使用する必要が

+0

私はアンラッピングをキャッチしようとする試みは一度もしていませんでした。しかし、あなたはそれにちょうどいい答えます。 私がこれに遭遇したusecaseは、SwiftyJSONとjsonの解析です。私はjsonレスポンス内に存在しないフィールドを単純にスロー(伝播)する子エンティティを含むエンティティを持っています。 同じイニシャライザを使用して同じことを実現しましたが、今度はさらに3行のコードがあります:P – Greg

+0

@Greg:スローされたエラーはどこかの場所で捕らえる必要があります。しかし、あなたの質問によく合うように言葉を変更しました。 –

5

この「自明」の例では、実行時例外を上げると投げの違いを見るのを助けることができますErrorTypeプロトコルに準拠したエラーE。

struct E: ErrorType{} 
func foo(bar:String?) throws { 
    if let error = bar where error == "error" { 
      throw E() 
    } 
    print(bar, "is valid parameter, but don't try to access bar.characters, it crash your code! (if bar == nil)") 
    // here is everything OK 
    let bar = bar! 
    // but here it crash!! 
    _ = bar.characters 
} 

do { 
    try foo("error") 
    // next line is not accessible here ... 
    try foo(nil) 
} catch { 
    print("\"error\" as parameter of foo() throws an ERROR!") 
} 
do { 
    try foo(nil) // fatal error: unexpectedly found nil while unwrapping an Optional value 
} catch { 

} 

それは実行時例外を上げる

"error" as parameter of foo() throws an ERROR! 
nil is valid parameter, but don't try to access bar.characters, it crash your code! (if bar == nil) 
fatal error: unexpectedly found nil while unwrapping an Optional value 

を印刷しますが、あなたのコード内で致命的なエラーです。

関連する問題