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 = Bar()
bar?.doSomething() // Valid
bar!.doSomething() // Valid
所以我的问题是,什么是调用一个可选的变量的方法最好的方式,我个人使用:
if bar != nil {
bar!.doSomething()
}
或将条.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()
这样做的原因是因为可选链接返回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
可以是有条件在年底完成,但是这意味着你仍然必须引入额外的代码来检查它是否被设置。它不会是短得多。)
有两个新的花样:-)
当你
bar?.doSomething()
这意味着,如果酒吧是零,也不会继续DoSomething的方法,但返回一个零。如果你想处理它为零的情况,你应该检查一个对象是否包含零。你也可以像这样做,通过可选的结合:
if let unwrappedBar = bar {
unwrappedBar.doSomething()
} else {
doSomeOtherThing() // In case it's nil
}
这使得可用的,如果让语句称为unwrappedBar暂时不变内的值(你可以给它任何其他的名字,如果你想),如果不是零。
您还可以使用更短的语法与可选的链接和合并操作:
bar?.doSomething() ?? doSomeOtherThing()
下面是关于不同的方式来访问可选值的更多信息:https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID330
伟大的,我应该使用**,如果让更多的经常 – 2015-03-13 09:20:15
这实际上不是闭包。 – 2015-03-13 12:57:53
@StefanArentz这是真的,谢谢。希望现在是正确的。 :) – alkku 2015-03-14 07:26:36
bar?.doSomething()
是调用的最佳方式一个可选变量的方法。如果酒吧不是零,它只会叫做某事。你写最少的代码,这是完全一样实现一个if let
检查
if let bar = bar {
bar.doSomething()
}
我认为这是更好的建议比'总是使用'如果让''。这种形式存在的原因是:它很简洁。 'if let'仍然有用,但在我看来并不适用于单个方法调用 - 如果您多次使用'bar',那么'if let'可能会更好。 – 2015-03-13 13:00:01
经验法则:每次你可以避免写一个'!',这样做(除了否定'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