我认为这是不好的建议,以避免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()
这样做的原因是因为可选链接返回nil
尽快因为它在链中遇到nil
。而且由于UIImageView
有一个image: UIImage?
,它取那个零值。即使它来自一个ImageGenerator?
当与无合并运算,??
组合是更加有用。
现在,你可以把这个代码..
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
}
..如果你没有使用可选链接和无合并操作员。
(是的myView.image = DefaultImage
可以是有条件在年底完成,但是这意味着你仍然必须引入额外的代码来检查它是否被设置。它不会是短得多。)
有两个新的花样:-)
经验法则:每次你可以避免写一个'!',这样做(除了否定'Bool')。这包括例如强制downcast'as!'。 '!'的意思是'嘿!不要这样做!这很危险!我警告过你!' – 2015-03-13 09:07:17
'!'的意思是我确切地知道我在做什么!我是开发人员,我决定如何运行我的程序!这不取决于某个变量来决定是否应该调用一个方法!'。在我看来Objective-C开发人员倾向于过度使用'?'。如果你可以将可选的东西链接在一起,而且不应该是可选的(从软件设计的角度来看),那么你正在模拟Objective-C中友好的零。 – 2015-03-13 09:13:11
@MatthiasBauch'!'表示'我是开发者,我从不犯错!我的程序总是完全按照!我决定!' 在我看来,'!'的意思是简单的'这不应该是零,不要继续,如果它。' – Krzak 2015-03-13 09:20:26