The Swift Programming Language guide has the following example:
class Person {
let name: String
init(name: String) { self.name = name }
var apar
Some big picture perspective to add to the other useful but more detail-centric answers:
In Swift, the exclamation point appears in several contexts:
let name = nameLabel!.text
var logo: UIImageView!
logo.image = thing as! UIImage
try! NSJSONSerialization.JSONObjectWithData(data, [])
Every one of these is a different language construct with a different meaning, but they all have three important things in common:
When you use !
in Swift, you are essentially saying, “Hey, compiler, I know you think an error could happen here, but I know with total certainty that it never will.”
Not all valid code fits into the box of Swift’s compile-time type system — or any language’s static type checking, for that matter. There are situations where you can logically prove that an error will never happen, but you can’t prove it to the compiler. That’s why Swift’s designers added these features in the first place.
However, whenever you use !
, you’re ruling out having a recovery path for an error, which means that…
An exclamation point also says, “Hey Swift, I am so certain that this error can never happen that it’s better for you to crash my whole app than it is for me to code a recovery path for it.”
That’s a dangerous assertion. It can be the correct one: in mission-critical code where you have thought hard about your code’s invariants, it may be that bogus output is worse than a crash.
However, when I see !
in the wild, it's rarely used so mindfully. Instead, it too often means, “this value was optional and I didn’t really think too hard about why it could be nil or how to properly handle that situation, but adding !
made it compile … so my code is correct, right?”
Beware the arrogance of the exclamation point. Instead…
Every one of these !
constructs has a ?
counterpart that forces you to deal with the error/nil case:
if let name = nameLabel?.text { ... }
var logo: UIImageView?
logo.image = thing as? UIImage
try? NSJSONSerialization.JSONObjectWithData(data, [])
If you are tempted to use !
, it is always good to consider carefully why you are not using ?
instead. Is crashing your program really the best option if the !
operation fails? Why is that value optional/failable?
Is there a reasonable recovery path your code could take in the nil/error case? If so, code it.
If it can’t possibly be nil, if the error can never happen, then is there a reasonable way to rework your logic so that the compiler knows that? If so, do it; your code will be less error-prone.
There are times when there is no reasonable way to handle an error, and simply ignoring the error — and thus proceeding with wrong data — would be worse than crashing. Those are the times to use force unwrapping.
I periodically search my entire codebase for !
and audit every use of it. Very few usages stand up to scrutiny. (As of this writing, the entire Siesta framework has exactly two instances of it.)
That’s not to say you should never use !
in your code — just that you should use it mindfully, and never make it the default option.