可选项和展开

时间:2017-01-29 04:23:35

标签: swift optional forced-unwrapping

我想要完成的是 - 我有两个文本字段,如果用户名文本字段print()或密码字段.isEmpty,我想.isEmpty向控制台发送消息}。我注意到的第一件事是文本字段是可选的,因为它们当然可以是空的。那么有人可以向我解释以下代码示例背后的一些语法和推理吗?

Q1:为什么我必须在.isEmpty之后解开包装?

if(self.username.text?.isEmpty)! {
    print("Something!")
}

Q2:为什么在包含或运算符时此语法不起作用?

if(self.username.text?.isEmpty || self.password.text?.isEmpty)! {
    print("Please provide username and password!")
}

问题3:为什么我不能在.isEmpty之后直接打开包裹?

if(self.username.text?.isEmpty! || self.password.text?.isEmpty!) {
    print("Please provide username and password!")
}

2 个答案:

答案 0 :(得分:2)

<强> Q1 : 您必须解包,因为text属性可以是nil。也许是因为它是一个有效的值,也许是因为它是Objective-C转换的工件而且它真的是nil_resettable

使用!是不安全的,因为无论何时访问文本它都会崩溃,如果没有设置它。

尝试这样的事情

if self.username.text?.isEmpty == false {
    print("Something!")
}

如果所需类型是可选的,则Swift对可选促销具有隐式非可选项。

起初它是Bool? == Bool,并且已更改为Bool? == Bool?

Q2 :为什么在包含或运算符时此语法不起作用?

let a: Bool? = self.username.text?.isEmpty
let b: Bool? = self.password.text?.isEmpty
let c = a || b // the problem here is that `Bool?` doesn't implement 
               // the operator `||` as it's not clear how this would
               // work with optionals.

你想这样做:

guard let username = self.username.text,
   let password = self.password.text,
   !username.isEmpty,
   !password.isEmpty {

    print("Please provide username and password!")
    return
}

// code using username as String and password as String (not optionals)

Q3

您需要修复括号。

if (self.username.text?.isEmpty)! || (self.password.text?.isEmpty)! {
    print("Please provide username and password!")
}

请记住,不要在生产代码中使用!。这是不安全的。使用 Q2 中的变体。

答案 1 :(得分:0)

  

Q1:为什么我必须在.isEmpty之后解开包装?

if(self.username.text?.isEmpty)! {
    print("Something!")
}

if语句结构会强制您在正文中使用true/false,以简化:

let condition = false

if condition {...}

当您打开此语句self.username.text?.isEmpty时,您告诉编译器“我保证它永远不会nil”,即使它可能是。{/ p>

  

Q2:为什么在包含或运算符时此语法不起作用?

or / and运算符的输入之前相同的原因必须不是nil(解包)。

请注意以下行。如果您尝试评估此语句,您将看到您正在尝试打开布尔值,并将两个选项作为参数。

if(self.username.text?.isEmpty || self.password.text?.isEmpty)! {
  

问题3:为什么我不能在.isEmpty之后直接解包?

我在这里猜测,基于您提出的问题。

isEmpty不是可选的,它可以是true / false,因此无法解包。

此声明self.username.text?.isEmpty是可选的,可以是true/false/nil,可以解包。

我希望有助于使事情更清楚。阅读optionals并分析Apple的代码示例可能会有所帮助。