Swift Optionals - Different ways of unwrapping

青春壹個敷衍的年華 提交于 2019-12-02 03:20:29

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!