2016-12-01 12 views
1

これら2つの構文に違いはありますか?そうでなければ、どんな利益ですか?Swift: "Where"と "If"の場合

if let userName = userNameTextField.text where userName.characters.count > 0, 
     let password = passwordTextField.text where password.characters.count > 0, 
     let confirmation = confirmationTextField.text where confirmation == password 
    else { 
     return false 
    } 

と:

if userNameTextField.text?.characters.count > 0 && 
     passwordTextField.text?.characters.count > 0 && 
    confirmationTextField.text == passwordTextField.text 
    { 
     return false 
    } 

答えて

6

まず第一には、オプションの結合条件でwhere節が,に置き換え、スウィフト3.0で廃止されていることに注意してください。

すなわち、開封されない任意の連鎖から任意結果

let opt: Int? 

/* Swift < 3 */ 
if let opt = opt where opt == 42 { /* ... */ } 

/* Swift >= 3 */ 
if let opt = opt, opt == 42 { /* ... */ } 

第二に、あなたの第二の例のブロックは習慣、スイフト> = 3.0でコンパイル。リテラルにoptionalsの比較は、以下の実施の提案に従って、スウィフト3.0(おかげ@MartinR)で削除されました:

userNameTextField.text?.characters.count > 0 && 
/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    this is an optional that, for Swift >= 3.0, needs to be unwrapped 
    prior to comparing it to the integer literal */ 

さて、あなたのに答えて進んでください "isr私たちは、あなたがしたい場合userNameTextFieldのオプションStringプロパティtextの値をバインドすることを選択することができるスウィフト3.

  • 固定あなたの二つのオプションを見て仮定電子任意の違い...」質問、ヤウドのみ(""textプロパティがnilまたは空でないことを確認したい場合、あなたは賛成で結合または単にそのcharacter.count
をチェック省略することができればを次のブロック、または
  • でそれを使用します

    例:

    struct Foo { 
        var bar: String? 
    } 
    var foo = Foo() 
    
    /* if you want to use foo.bar within the if block */ 
    if let str = foo.bar, str.characters.count > 0 { 
        // do something with str ... 
        print(str) 
    } 
    
    /* if you only need to ascertain foo.bar is not nil 
        and not empty */ 
    if (foo.bar?.characters.count ?? 0) > 0 { 
        // do something with str ... 
        print("not empty") 
    } 
    
    // alternatively ... (not nil or empty) 
    if !(foo.bar?.isEmpty ?? true) { 
        // do something with str ... 
        print("not empty") 
    } 
    

    あなたは単にascertationに障害が発生した場合には、あなたの代わりにifguard文を使用して好むことができ、後者を把握し、falseを返すようにしたい場合:

    guard (foo.bar?.characters.count ?? 0) > 0 else { return false } 
    // ... if no false return, proceed with app flow here ... 
    
    // alternatively ... 
    guard !(foo.bar?.isEmpty ?? true) else { return false } 
    
  • +0

    2番目の例はSwift 2でコンパイルします(私が間違っていない限り)。オプションを比較する機能は、Swift 3で削除されました。 –

    +0

    @MartinRああ、私はそれが今まで可能だったのか分かりませんでした! – dfri

    0

    どちらのバージョンの作品私は最初のバージョンではletの代わりにguardを使うつもりであったと思います。スウィフト3で

    は、次の操作を行うにしたい:

    guard 
        let userName = userNameTextField.text, 
        let password = passwordTextField.text, 
        let confirmation = confirmationTextField.text, 
        userName.characters.count > 0, 
        password.characters.count > 0, 
        confirmation == password 
    else { 
        return false 
    } 
    
    +0

    スウィフト2ではオプション記号と '>'を比較できます。 –

    +0

    あなたの他のコメントを見ました。私にはニュースだった! – ganzogo

    0

    他の回答の一部で説明したようスウィフト3にあなたのアプローチを使用してに問題があります。しかし、Swift 2を使用している場合、あなたの質問に対する私の答えは次のとおりです。

    2つの違いはまったく同じです。どちらの方法もゼロ値をテストしていて、値がnilでなければブール値テストを導入しています。そのカウントがゼロより大きい場合、あなたのラインの例、

    if let userName = userNameTextField.text where userName.characters.count > 0 
    

    のためにあなたはuserNameTextFieldがnilでないかどうかを確認するためにテストしていると、あなたがテストしています。この行にも同じことが適用されます。

    if userNameTextField.text?.characters.count > 0 
    

    非常に短くて読みやすいという点を除いて、この行が適用されます。

    両方のアプローチが 'if'ステートメント内にあるため、両方とも真または偽と評価され、同じ目的を達成します。

    ただし、 'where'句を使用すると、2つの間に基本的なセマンティックリンクがあるかどうかにかかわらず、バインディングまたはパターンの後にブールテストを導入できます。だから私は基本的にuserNameTextFieldと年齢との間には意味的なリンクはありません、

    if let userName = userNameTextField.text where age > 0 
    

    「どこ」節でこれを行うことができます。あなたが想像しているように、それはあなたが意図したものではない可能性があり、これはすぐにエラーにつながる可能性があります。