Swift安全解包可选字符串和整数

8

当我即将触发第二个视图的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!
}

这一切都能够正常工作,我从未因为变量未包装或空值而出现错误。但是,有没有更简单的方法来做到这一点呢?

目前感觉自己在检查的时候过于繁琐。

5个回答

12

我可以想到三种替代方案。

  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
}
  • guard/let. 如果它们出现在像 setupViews() 这样的函数中,则可以这样将其一行化:

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

  • 对于第四和第五个选择,请参考vadian的答案和Martin R对问题的评论。 - keithbhunter

    8
    您可以使用 Nil Coalescing Operator,如文档所述:
    nil coalescing operator (a ?? b) 可以展开包含值的可选类型 a,或者返回默认值 b,如果 a 为空。 表达式 a 总是可选类型。表达式 b 必须与 a 中存储的类型匹配。
    nil coalescing operator 是以下代码的简写形式: a != nil ? a! : b

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

    这与您的JSON相同


    1
    你不需要在第一个视图中检查nil条件。 请按照以下代码操作:
    toView.time = ads[indexPath.row]["unix_t"] as? Int
    toView.title = ads[indexPath.row]["title"] as? String
    第二个视图中的时间和标题变量是可选的。因此,当你将值分配给toView.time和toView.title时,它将分别分配时间和标题类型的值或nil。

    1

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

    由于只传递非可选值,您可以声明变量为非可选的。

    var time = 0
    var title = ""
    

    并设置标签

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

    Swift的强类型系统极力推荐首先考虑“我能否在不使用可选项的情况下完成这个任务?”如果没有其他选择,则使用可选项。

    你的意思是在第二个视图控制器中为它们提供“虚假”的值吗?这样,如果在segue中从未传递任何值,它将回退到虚拟值。 - user2636197
    @user2636197 你需要决定如何处理错误。如果不传递一个值是有效的,那么使用可选项。如果不传递一个值应该被视为错误,则可以直接使用强制解包而无需检查。 - Sulthan
    如果这个解决方案符合您的设计要求,是的。 - vadian

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接