所以我知道'!'之间的区别和'?',我只想知道在调用可选变量的方法时使用它们的最佳方式是什么
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 Chaining 在 chain 中遇到 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/