Swift:调用可选变量的方法

标签 swift

所以我知道'!'之间的区别和'?',我只想知道在调用可选变量的方法时使用它们的最佳方式是什么

var bar: Bar? = nil

bar?.doSomething()  // this will be valid, but wouldn't call doSomething
bar!.doSomething() // Given error: EXC_BAD_INSTRUCTIONS (Obviously)

但是当 'bar' 不为 nil 时,这两个方法调用都是有效的。

bar = Bar()
bar?.doSomething()  // Valid
bar!.doSomething()  // Valid

所以我的问题是,调用可选变量方法的最佳方式是什么,我个人使用:

if bar != nil {
    bar!.doSomething()
}

或者 bar?.doSomething() 会完全一样吗?

最佳答案

我认为避免 bar?.doSomething() 并始终使用 if let bar = bar { ... } 是个糟糕的建议。

主要有两个原因:

首先,bar?.doSomething() 更简洁。如果您编写的 if let 条件表达式中只有一个语句,那么您可能应该问问自己,您是否不想将该代码与较短的版本放在同一行中。

虽然这是完全合法的代码..

if let thing = thing {
    thing.bar()
}

.. 以下是合法的,只是短了很多..

thing?.bar()

其次,更重要的是这个问题的核心,它们是不一样的! if let 是一个组合测试、可选的解包和赋值,而 bar? 执行称为可选链接的操作。

后者在许多情况下非常有用,可以让您编写更好的代码。例如:

它可以用来代替这个..

var imageGenerator: ImageGenerator?

if let generator = imageGenerator {
    myView.image = generator.generateImage()
} else {
    myView.image = nil
}

.. 只需:

myView.image = self.imageGenerator?.generateImage()

这是因为 Optional Chainingchain 中遇到 nil 时立即返回 nil >。由于 UIImageView 有一个 image: UIImage?,它采用 nil 值。即使它来自 ImageGenerator?

当与 Nil 合并运算符 结合使用时,它会更有用,??

现在你可以把这段代码..

var imageGenerator: ImageGenerator?

if let generator = imageGenerator {
    myView.image = generator.generateImage()
} else {
    myView.image = DefaultImage
}

..进入..

myView.image = generator?.makeImageGenerator() ?? DefaultImage

.. 这样更简洁。

而且因为可选链适用于 ..你甚至可以做类似的事情:

myView.image = delegate?.makeImageGenerator()?.generateImage() ?? DefaultImage

这会变成..

if let delegate = delegate {
    if let generator = delegate.generatorForImage() {
        if let image = generator.generateImage() {
            myView.image = image
        } else {
            myView.image = DefaultImage
        }
    } else {
        myView.image = DefaultImage
    }
} else {
    myView.image = DefaultImage
}

.. 如果您没有使用可选链接Nil 合并运算符

(是的,myView.image = DefaultImage 只能在最后有条件地完成,但这意味着您仍然需要引入额外的代码来检查它是否已设置。它不会更短。 )

那里,两个新技巧:-)

关于Swift:调用可选变量的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29028230/

相关文章:

swift - 使用监听器更新任何 View Controller

ios - 重置 UITableViewCell 无法正常工作/未选择的单元格在滚动后显示为选中

ios - swift 5 : Binary operator '==' cannot be applied to operands of type 'AnyObject?' and 'UIView?'

arrays - 将一个数组与另一个数组进行比较时如何找到所有单个空闲位置?

swift - 中心 CAShapeLayer