2016-05-05 11 views
-1

以前に宣言された変数にオプションのバインドを使用できませんか? if letguardが存在するようになったのはこのような自然なことです。Swiftでのオプションのバインディングと管理スコープの使用

var jsonData:AnyObject? 

if jsonData = try? NSJSONSerialization.JSONObjectWithData(data, options: []) { 
    //use jsonData! safely 
} 
//still be able to use jsonData? 

それとも

var jsonData:AnyObject? 

guard jsonData = try? NSJSONSerialization.JSONObjectWithData(data, options: []) else { 
    print("Could not parse JSON") 
} 
//still use jsonData? 

なぜスコープの制限:私はの行で何かを考えていますか?いつでもどこでも変数を使用するために開いたままにしておきましょうか?

私はそもそもif letguardの本来の目的ように見えたものですどのオプションをアンラップ(条件付きコードを実行)/割り当てるときに、2つの別々のステートメントを避けているやろうとしています:

var jsonData: AnyObject? 

jsonData = try? NSJSONSerialization.JSONObjectWithData(data, options: []) 
if(jsonData != nil) { 
    //use jsonData! safely 
} 
//still use jsonData? 

これについては、クールな方法がありますか、または2つのステートメントを使用する唯一のオプションはありますか?再びコードを見ている

EDIT

、私は特定の重要なオプションの変数をアンラップ流れの主要なリダイレクトなし/割り当てる際print()メッセージにしようとしたとき、このシナリオの私の主な用途があることがわかります。ここに私の実際コードからキー文は、次のとおりです。

私は if letguardが正確にこれらの二つの文をマージするために作られたが、私はそれは、彼らが何であったか、実際にはないことを感じを得ているという印象の下にあった
jsonData = try? NSJSONSerialization.JSONObjectWithData(data, options: []) 
if(jsonData == nil) { 
    print("Could not parse data") 
} 

のために意図された。私はCode Reviewに私の質問のより明確な説明を掲載したいと思う。

+1

'jsonData'が' nil'の場合は使用する必要がありますか?それが 'nil'だった場合は、次の行で何をしていますか?私にとって、それに対する答えは主にあなたの状況に対処する最善の方法に影響します。 – nhgrif

+0

@nhgrif後で起こるのは、HTMLステータスコードが成功したかどうかを確認し、成功した失敗ステータスコードの4つの組み合わせをnil-notnil jsonDataで処理する必要があることです。それは後で 'nil'をチェックしなければならないことを意味しますが、これらのif文をすべて減らそうとしています。 – frezq

+1

実際のコードを掲載することはできますか?実際に具体的な実装があり、それが期待どおりに動作していても、より洗練された、より簡潔な実装方法を知りたい場合は、[Code Review](http://codereview.stackexchange.com/help/on-topic)。現在の実装を実際に見ることなく、多くのアドバイスをすることは難しいでしょう。 – nhgrif

答えて

1

それはletなしguardだけブール式あなたは、この場合に!を使用しないでください

guard let jsonData = try? NSJSONSerialization.JSONObjectWithData(data, options: []) else { 
    print("Could not parse JSON") 
} 
// use jsonData 
1
// use jsonData! safely 

を評価し、guard letです。 if letの全体のポイントは、!の危険性を避けることです。しかし、あなたの質問に、このIMOを行うための最善の方法は次のとおりです。言っ

let jsonData = try? NSJSONSerialization.JSONObjectWithData(data, options: []) 
if let jsonData = jsonData { 
    // use jsonData as itself 
} 

// use jsonData? as optional 

は、私は非常にまれにこのような状況に遭遇していない、それは悪い因数分解のコードを示していることがあります。いずれにしても、ここで1行削除すると言語をさらに複雑にする価値はあるが、Swiftをこのように変更するための魅力的なユースケースがある場合は、それがSwift-Evolutionプロセスの目的である。

+0

'jsonData!= nil'が成功した場合、' if'スコープ内の 'jsonData! 'はどのように安全ではないでしょうか? – vadian

+0

'jsonData'がローカルにスコープされている場合は、かなり難しいかもしれませんが、メンテナが安全なアンラッピングオプションを使用するのに十分シンプルなときに、メンテナがダブル、トリプル、とにかくすでに使用しています。 – nhgrif

+1

"現在のコードではクラッシュしません"と "安全"の違いがあります。 NULL可能なポインタは、使用する前に正しくチェックする限り、完全に安全です。しかし、これはプログラミングの歴史におけるクラッシュの最大の原因です。 '!'はまったく同じ方法で「安全」です。 Swiftはこの問題を避けるためにオプションを導入しました。 '! 'はコーナーケースのためのエスケープバルブです。通常の方法ではなく、オプションでアクセスできます。 –

0

私が知る限り、それはあなたが望むように機能します。運動場で次のように試してみてください。 printステートメントで使用されているmyDataの名前は、異なるスコープで異なる変数として動作します。

func indefinite() throws -> AnyObject? { 
    return "asd" 
    //return nil 
} 

var myData: AnyObject? 

if let myData = try indefinite() { 
    print("Unwrapped \(myData.dynamicType)") 
} else { 
    print("Optional \(myData.dynamicType)") 
} 

私は実際のコードを書いていた場合、私はおそらく代わりに... ...

if let safeData = try indefinite() { 
    print("Unwrapped \(safeData.dynamicType)") 

を使用すると思います。

+0

はい、それらは異なる変数として振る舞います(そして私はそれらが異なっていると思います - 私はあなたがmyDataという2つの異なる変数を持っていると信じています) 'if let'スコープの後のmyDataの値。申し訳ありませんが私の本来の目的は明確ではなかったが、あなたの助けに感謝。 – frezq

+0

**範囲内の**割り当てられた値を必要とする作業を行うだけではどうですか?これは基本的に 'if let'の定義です:アンラップが非ゼロ値を生成するスコープです。 –

+0

これは可能ですが、この特定のケースでは(と私はそれが珍しいとは思わない)、そのコードをスコープ内に制限することは、論理的な流れに対して直観的に直観的になります。私は[コードレビュー](http://codereview.stackexchange.com/questions/127600/i-want-to-run-some-conditional-code-based-on-a-regular-assignment-can)に関する質問を作成しました。私が何を意味するのか興味があれば、質問にはより多くのコードが含まれており、私の問題が何かを詳しく調べるのに時間がかかりました。より良い構造の提案があれば、私はそれらを聞いてみたいと思う。 – frezq

関連する問題