Over at Human Friendly there is a blog post about needing an AssertingNilCoalescing
operator: !!
. I get what is being said: you have an Optional
that shouldn’t be nil
(it’s an Optional
for many reasons, typically outside of your control such as a bridged item from ObjC). Sounds reasonable, after all, no one likes crashing apps and the alternative is to use the if-let
form to handle the case (or the shorthand ??
).
So instead of writing this:
assert(opt != nil)
let foo = opt ?? safeValue
You use the shorthand version:
let foo = opt !! safeValue
Sure, it’s more terse. However, and this is the main reason I do not like this pattern: it is introducing a class of bugs that Swift has intentionally chose to make hard to get into and the very reason some are choosing to rewrite everything in Swift.
We did indeed see surprising patterns in the causes of these bugs. I found myself repeatedly saying to myself or Janie that a particular bug wouldn’t have even compiled under Swift, or would have thrown an immediate exception. When we totaled up bugs like this, we found that 40% of bugs shipped to customers in the last three years would have been caught immediately by using Swift. The primary classes of these bugs were:
- Silent failures due to nil-messaging (emphasis added)
- Improperly handled NSErrors, or other Objective-C error failures
- Bad object typecasts
- Wrong enum lookup tables being used for values
Source: http://www.sunsetlakesoftware.com/2014/12/02/why-were-rewriting-our-robotics-software-swift
This operator is introducing the same exact semantics that some are trying to run away from.
If opt
is never supposed to be nil
, then do an assert
on it and log those errors using some sort of telemetry system or simply force unwrap it. The crash logs will help you find these issues and fix them, silently failing will not get you that information.
And you won’t find these issues in testing when using assert
unless you also test against debug
builds. If you are testing debug
builds instead of release
builds, then you really are not testing the product you’ll be giving your customers… but that’s a topic for another day.