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

Swift safely unwrapping optinal strings and ints

当我要为第二个视图触发我的 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 值引起的错误。但是有没有更简单的方法呢?

现在感觉自己查多了

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

if let title = title {
    titleLabel.text = title
}

和你的一样JSON

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

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

var time = 0
var title = ""

并设置标签

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

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

Can I accomplish this without optionals?

并且——如果没有其他选择——那么使用可选的。

我可以想到三种选择。

  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 ?? ""
    

您也可以使用 Nil Coalescing Operator,如 Docs 中所示:

The nil coalescing operator (a ?? b) unwraps an optional a if it contains a value, or returns a default value b if a is nil. The expression a is always of an optional type. The expression b must match the type that is stored inside a.

The nil coalescing operator is shorthand for the code below:

a != nil ? a! : b

您不需要在第一个视图中检查 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。