2016-12-01 72 views
1

這兩種語法有什麼區別嗎?如果沒有,有什麼好處?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,因爲從可選鏈接的可選結果不展開;比較自選到文字已在夫特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 */ 

現在,繼續回答你的「是Ë任何區別......」問題,假定我們看一下固定斯威夫特3.

  • 您的兩個選項,您可以選擇可選String屬性的值綁定的userNameTextFieldtext,如果你想在隨後,或
  • 如果你幾乎只需要確定的是,text屬性不nil或空("")if塊使用它,你可以省略有利於結合或簡單地檢查其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失敗則返回false,你可能更喜歡使用guard聲明,而不是if

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

第二個例子*在Swift 2中編譯*(除非我錯了)。在Swift 3中刪除了用於比較選項的功能。 –

+0

@MartinR啊,我不知道這是可能的,謝謝! – dfri

0

既不版本的Works在Swift 3.我認爲在第一個版本中,你的意思是使用guard而不是let

與SWIFT 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

你*可* *在Swift 2中用'''比較可選項。 –

+0

是的謝謝 - 看到你的其他評論。對我來說是新聞! – ganzogo

0

有使用你的斯威夫特3的方式,通過一些其他的答案的解釋問題。但是如果你使用Swift 2,以下是我對你的問題的回答。

這兩者完全一樣,只有一個區別。兩種方法都在測試一個零值,然後在值不爲零的情況下引入布爾測試。例如,在您的線路,

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

您正在測試,看看userNameTextField不是零,那麼你正在測試如果計數大於零。

if userNameTextField.text?.characters.count > 0 

除了它是短得多和可讀的。

因爲兩種方法都在'if'語句中,它們都評估爲真或假,並達到相同的目的。

但是,將它們分開的原因是,使用'where'子句,可以在綁定或模式之後引入布爾測試,而不管這兩者之間是否存在基礎語義鏈接。所以我基本上可以用'where'子句做這個,​​

if let userName = userNameTextField.text where age > 0 

userNameTextField和age之間沒有語義鏈接。你可以想像,這可能不是你想要的,這很快就會導致錯誤。