斯威夫特:“哪里”与“如果”

时间:2016-12-01 12:03:18

标签: swift if-statement where

这两种语法之间有什么区别吗?如果没有,有什么好处吗?

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
    }

3 个答案:

答案 0 :(得分:6)

首先,请注意可选绑定条件中的where子句在Swift 3.0中已弃用,替换为,

let opt: Int?

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

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

其次,你的第二个示例块不会在Swift&gt; = 3.0中编译,因为可选链接的可选结果未解包;根据以下实施的提案,在Swift 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 */

现在,继续回答你的&#34;是否存在任何差异...&#34; 问题,假设我们看一下为Swift 3修复的两个选项。

  • 您可以选择绑定String 的可选text属性userNameTextField的值,如果您想在后面的if块中使用它< / em>,或
  • 如果您只想确定text属性不是nil或空""),您可以省略有利的绑定或只是检查其character.count

E.g:

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")
}

如果您只是想确定后者并在确认失败时返回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 }

答案 1 :(得分:0)

这两个版本都不适用于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
}

答案 2 :(得分:0)

在Swift 3中使用您的方法存在问题,正如其他一些答案所解释的那样。但是如果您使用的是Swift 2,以下是我对您问题的回答。

两者完全相同,只有一个区别。两种方法都测试nil值,然后在值不为nil时引入布尔测试。例如,在你的行中,

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

您正在测试userNameTextField是否为nil,然后您正在测试其计数是否大于零。同样的事情适用于这一行,

    if userNameTextField.text?.characters.count > 0 

除了它更短更可读。

因为这两种方法都在'if'语句中,所以它们都评估为true或false并达到相同的目的。

然而,它们之间的区别在于,使用'where'子句,您可以在绑定或模式之后引入布尔测试,无论两者之间是否存在底层语义链接。所以我基本上可以用'where'子句

来做到这一点
    if let userName = userNameTextField.text where age > 0 

userNameTextField与age之间没有语义链接。你可以想象,这可能不是你想要的,这很快就会导致错误。