Nil Considered Harmful: How Optionals Work in Swift
One of my favorite features of Swift, Apple’s new programming language for iOS and OS X development, is how it handles nil values through Optionals. Optionals address the many problems created by nil values, such as inadvertently using nil (null) values from function outputs or not initializing fields. These easy-to-make mistakes usually lead to confusing and difficult-to-debug runtime crashes, especially in compiled languages such as Java, C++, and Objective-C.
Swift Optionals address the nil problem by maintaining a distinction between variables that have a value and variables that may have the absence of any value (Optionals). Let’s take a look at the basics of how they work!
Regular (Non-Optional) Variables
Let’s start with regular variables, declared with just the type name:
Any regular instance variable in Swift must have a non-nil value set before it is used. That ensures that regular variables will always have a value. For instance, the following code is incorrect:
So, what does this mean? For instance, if a function returns a regular variable, you are guaranteed to receive a value, and do not have to worry about receiving nil and crashing. Also, if a function signature takes a regular variable as a parameter, it is guaranteed to receive a value.
The behavior of regular variables is different than that of variables in other languages. Take Java for example:
This would crash with a NullPointerException because t
was not initialized
when doubleValue
tried to access it.
Optional Variables
So, what if you need to have nil values? Take, for instance, casting a String to an Int:
Casting a String to an Int can fail. If it fails, instead of throwing an
exception or crashing the program, the cast will return nil
. Thus,
to handle it, we can store the output into an Optional type, declared
with a ?
after the type:
The ?
indicates that that particular variable may or may not have a
value. These Optionals do not have to be initialized in the constructor
because they can be nil at any time.
So, how do we use Optional variables in places where we want non-nil values? You can do this in three different ways, each suiting a specific purpose.
1. if let
Optional Binding
First, a slight segue: constants in Swift (declared with let
instead of var
) are implicitly non-nil, because a nil constant
would be quite meaningless.
So, to run some code only if an Optional has a non-nil value, we can
use the if let
construct:
This code states that if the Optional returned from the cast contains an
Int, assign it to definitelyNumber
and run the code inside the if
.
Otherwise, move on.
One if let
can be used on multiple optionals, to make sure
that all variables you need in a code block have an assigned value.
if let
is very useful in practice, and helps safely and efficiently
handle nil
cases, in ways explicitly stated by the developer.
It’s a clean way to handle nil
in code and describe exactly how you
want your program to behave given an Optional.
2. ?
Optional Chaining
if let
is a powerful tool, but can lead to long, far indented code,
especially when you have to call many functions that return optional
values and use them. To optimize this, you can use ?
after fields
and functions: this will run the code following the ?
only if
the output of the optional is not nil
.
Optional chaining is short and sweet, and works well when you want to call a function on an object if the object exists.
3. Forced Unwrapping
This is arguably the simplest technique we can use, and the most dangerous.
We can force the wrapping of an Optional to a regular variable using a !
following the variable name. If the Optional contained a null value, this
could result in your program crashing!
You can also chain forced unwraps:
Forced unwrapping should only be used in two situations: when you are
confident that a value does not contain nil
, or when you want your
program to crash if a value is not present (for example, when checking for
existence of essential data values for your app).
Implicitly Unwrapped Optionals
Finally, there are cases when you are sure that an optional will always
have a value, or when its absence of a value means critical failure for
your program. In this case, an implicitly unwrapped optional, declared
with !
after the type, may be the best choice. Implicitly unwrapped
optionals can be nil
but never need to be unwrapped, potentially saving
you time and code, at the risk of crashing on nil
values.
Implicitly unwrapped optionals should not be used if there is a chance
of it becoming nil
sometime during execution, because this could
easily lead to crashes. When in doubt, use a regular optional or a
regular, non-optional variable.
That’s it!
Those were the basics of Optionals in Swift! If you’re interested in more advanced features of Swift Optionals or want to learn more about the language, check out the links below:
- Swift Language Guide: Apple’s guide to the Swift Programming Language.
- Swift Resources: Videos and sample code for Swift.
- Swift Tutorials: Tutorials and articles on Swift on raywenderlich. This is a great resource if you want to learn about Swift and iOS development!
Finally, stay tuned to the blog for future posts on Swift, and thanks for reading!