【问题标题】:Optionals and unwrapping可选和展开
【发布时间】:2017-01-29 04:23:34
【问题描述】:

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

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

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

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

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

Q3:为什么.isEmpty后面不能直接解包?

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

【问题讨论】:

标签: swift optional forced-unwrapping


【解决方案1】:

第一季度: 您必须打开包装,因为text 属性可以是nil。可能是因为它是一个合法的值,也可能是因为它是Objective-C转换的神器,它确实是nil_resettable

使用! 是不安全的,因为如果未设置,则在您访问文本时它可能会崩溃。

试试这样的

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

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

一开始是Bool? == Bool,后来改成了Bool? == Bool?

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

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)

第三季度

您需要修正括号。

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

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

【讨论】:

    【解决方案2】:

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

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

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

    let condition = false
    
    if condition {...}
    

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

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

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

    请注意下面的行。如果您尝试评估此语句,您将看到您正在尝试解开一个布尔值,并使用两个可选参数作为参数。

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

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

    根据您提出的问题,我在这里猜测。

    isEmpty 不是可选的,它可以是真/假,因此不能解包。

    这条语句self.username.text?.isEmpty 是可选的,它可以是true/false/nil 并且可以被解包。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-30
      • 1970-01-01
      • 2022-12-19
      • 2022-01-26
      • 1970-01-01
      • 2021-06-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多