【问题标题】:Swift safely unwrapping optinal strings and intsSwift 安全地展开可选字符串和整数
【发布时间】:2016-10-29 21:31:00
【问题描述】:

当我要为第二个视图触发我的 segue 时,我还会发送一些像这样的值:

if let aTime = ads[indexPath.row]["unix_t"].int {
    toView.time = aTime
}

if let aTitle = ads[indexPath.row]["title"].string {
    toView.title = aTitle
}

在第二个 VC 中,我声明了如下变量:

var time: Int?
var title: String?

这就是我打开这些值的方式:

if time != nil {
   timeLabel.text = String(time!)
}

if title != nil {
   titleLabel.text = title!
}

这一切都有效,我从来没有得到任何由未包装的变量或 nil 值引起的错误。但是有没有更简单的方法呢?

现在感觉我检查的太多了

【问题讨论】:

    标签: swift swifty-json forced-unwrapping


    【解决方案1】:

    我能想到三种选择。

    1. if/let。与您当前的选项非常相似,但您不必隐式展开。

      if let time = time {
          timeLabel.text = "\(time)"
      }
      
      if let title = title {
          titleLabel.text = title
      }
      

      您甚至可以在同一行展开它们。这样做的缺点是,如果其中一个是 nil,则不会设置任何标签。

      if let time = time, let title = title {
          timeLabel.text = "\(time)"
          titleLabel.text = title
      }
      
    2. guard/let。如果这些在setupViews() 之类的函数中,那么您可以像这样单行展开:

      func setupViews() {
          guard let time = time, let title = title else { return }
          timeLabel.text = "\(time)"
          titleLabel.text = title
      }
      
    3. 您可以使用默认值和?? 运算符快速展开。

      timeLabel.text = "\(time ?? 0)"
      titleLabel.text = title ?? ""
      

    【讨论】:

    • 对于第 4 和第 5 替代方案,请参阅 vadian 的回答和 Martin R 对问题的评论。
    【解决方案2】:

    您也可以使用Nil Coalescing Operator 中的Docs

    nil 合并运算符 (a ?? b) 如果可选 a 包含值,则将其展开,如果 a 为 nil,则返回默认值 b。表达式 a 始终是可选类型。表达式 b 必须匹配存储在 a 中的类型。

    nil 合并运算符是以下代码的简写:

    a != nil ? a! : b

    【讨论】:

      【解决方案3】:
      if let time = time {
          timeLabel.text = "\(time)"
      }
      
      if let title = title {
          titleLabel.text = title
      }
      

      这和你的 JSON 一样

      【讨论】:

        【解决方案4】:

        是的,你检查的太多了(两次)。

        由于只传递非可选值,因此您可以将变量声明为非可选

        var time = 0
        var title = ""
        

        并设置标签

        timeLabel.text = "\(time)"
        titleLabel.text = title
        

        Swift的强类型系统强烈推荐优先考虑

        我可以在没有选项的情况下完成这个吗?

        并且 - 如果没有其他选项 - 则使用可选项。

        【讨论】:

        • 您的意思是在第二个 VC 中给他们“虚拟”值?这样它就会回退到虚拟值,以防在 segue 中从未传递任何值
        • @user2636197 你必须决定如何处理错误。如果不传递值是有效的,则使用可选项。如果不传递值应该被视为错误,那么您可以直接使用强制展开而不进行检查。
        • 如果此解决方案适合您的设计,是的
        【解决方案5】:

        您不需要在第一个视图中检查 nil 条件。 请按照以下代码:

        toView.time = ads[indexPath.row]["unix_t"] as? Int

        toView.title = ads[indexPath.row]["title"] as? String

        第二个视图中的时间和标题变量是可选的。所以,当你给 toView.time 和 toView.title 赋值时,它要么分别赋值为 time 和 title 类型的值,要么赋值为 nil。

        【讨论】:

          猜你喜欢
          • 2016-04-24
          • 1970-01-01
          • 2015-10-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-08
          • 2015-06-09
          • 1970-01-01
          相关资源
          最近更新 更多