问题
I'll just get right to it:
What's the difference between:
var test: String?
test = "this is an optional string"
if test != nil {
println("\(test!) IS NOT nil")
} else {
println("test is nil")
}
and
if let test = test {
println("\(test) IS NOT nil")
} else {
println("test is nil")
}
Both output the same results in a playground.
I know implicitly unwrapping is not considered safe (in most cases) but, here I'm checking whether or not the values are nil before unwrapping?
Are both methods valid and are there different scenarios where one is considered the better choice?
回答1:
Are both methods valid, and are there different scenarios where one is considered the better choice?
The if-let
form is the better choice in every case that it can work in. The correct way to pronounce !
is "I swear on my program's life," because you are.
Your example is the trivial form, and in the trivial form it's difficult to see how a problem might occur. I just tested this against nil
. What could go wrong? But software grows and software changes. Your != nil
check is identical to the C and Java check people have used for decades, and have led to crashing programs for decades. It is in fact very easy to miss a necessary-but-not-compiler-required test. And people do all the time.
When you rearrange you code and move the println
into a function, did you remember to also move the if
test? In a large function, where the if
tests might be done at the top, did you remember to do all of them before using !
? Did that continue to be true after refactoring? After bug fixes? For every code change?
If you forget to test for nil
with if-let
, then the compiler will stop you. If you forget to test with != nil
, a crash will stop you; hopefully, if you're very lucky, in unit testing. If not so lucky, in the field.
That said, if-let
is not the only good mechanism. You can also map
optionals, use nil coalescing (??
), optional chaining (?.
), and these are all excellent tools for avoiding bugs. But Apple chose !
(which in Unix is seriously called "bang") on purpose. It is dangerous, and should be used only with great care when other options are unworkable.
In the end, if you write code perfectly, then no compiler-imposed safety is required. You could write your code in assembler, entirely with global memory, and avoid many of the costs of abstraction that we use. But human programmers tend to make lots of small mistakes, and that's why you should avoid !
.
来源:https://stackoverflow.com/questions/27743774/swift-optionals-different-ways-of-unwrapping