Video
What are Optionals?
Optionals are a type that represents either a wrapped value or the absence of a value.
Put simply, optionals are a type that can contain a value or might contain nil
, the absence of a value. Optionals are an important language feature that allows you to write safe code, properly handling missing values, and avoid dealing with unexpected errors or behaviors at run time.
Declaring Optionals
An optional type is denoted with the wrapped type's name with a trailing question mark (?).
For example, an integer type is Int
while an optional integer type is Int?
. This is the same with all other data types like String
and String?
.
In the example below, both values are optionals as they are explicitly declared as optionals.
Optionals also support type inference, where the compiler will automatically infer the type of your value.
In this example, Int("…")
initializer may return a nil
value as it attempts to convert a String
into an Int
type.
Implicitly Unwrapped Optionals
Implicitly Unwrapped Optionals are declared with a trailing exclamation mark (!). While still an optional value like the ones with the trailing question mark (?), they behave differently.
Unlike regular optionals (like Int?
and String?
), which requires you to unwrap the value to access the underlying value, using implicitly unwrapped optionals (like Int!
and String!
) automatically unwraps itself when accessed. This means you will not need to handle optionals with the methods below every time you use value—but if value is nil when you try to use it, it will cause the application to terminate or crash.
Handling Optionals
Optional Binding
Optional binding allows you to conditionally bind the wrapped value of an Optional instance to a new variable, using if-let
, guard-let
, or a switch-case
.
if-let
If-let allows you to set the unwrapped value to a new property and you can use the else
clause to handle a case when the value is nil.
This will also work within SwiftUI with conditional rendering.
if-let shorthand
In Swift, when using if-let to optionally bind to a property, the optional variable's name is often reused for the optionally bound property.
You can use the shorthand to avoid typing if let name = name
and transform that simply into if let name
. This makes it faster to write optional bindings.
guard-let
Guard allows you to set the unwrapped value to a new property and perform an early-exit if the wrapped value is nil.
The main benefit of guard-let over if-let is the ability to exit-early and avoid nesting things too deeply. Within the guard's else clause, you can write code to handle if the wrapped value does not exist, you will need to end it off with a return
if within a function, or break
—to end the loop or continue
—to move onto the next iteration if within a loop.
While guard-let
works within SwiftUI's View Builder code, it is generally better to use if-let
.
guard-let shorthand
In Swift, when using guard-let to optionally bind to a property, the optional variable's name is often reused for the optionally bound property.
You can use the shorthand to avoid typing guard let name = name
and transform that simply into guard let name
. This makes it faster to write optional bindings.
Switch Statements
Switch Statements allows you to handle the optional value using the .some
condition. You can also use it to check the wrapped value against other values.
In this example, the wrapped value, optionalNumber
is checked against 42, then it is optionally bounded to the value
property in the .some(let value)
case. Finally, the default case handles any nil values.
In the above example, the default case can also be replaced with case nil:
to handle missing values.
This method, like if-let works well with SwiftUI's conditional rendering.
Optional Chaining
Optional chaining allows you to safely access the properties and methods of a wrapped instance, use the optional chaining operator (?).
For example, if you want to access the description
property (that creates a textual description) of an optional value, you can use optional chaining to "pass along the optional value".
In the above example, if Int(userFavoriteNumber)
evaluates to nil, the description
constant will be set to nil.
You can also use this to access functions and methods. If the value is nil, the method will not run.
As the name suggests, you can chain it. When chaining, you will need to use the optional chaining operator (?) whenever you are dealing with an optional property or method that returns an optional value.
Nil-Coalescing Operator
The nil-coalescing operator (??) allows you to supply a default value in case the Optional instance is nil.
In this example, if userFavoriteNumber
cannot be converted to an integer, the favoriteNumber
constant will be set to 100.
Unconditional Unwrapping
⚠️ Warning
Only use unconditional unwrapping when you are certain the value will return a non-nil result.
Unconditional unwrapping will terminate the application if the value is nil.
You can use the value by using the forced unwrap operator (!) to unconditionally unwrap a value.
In the example below, if myOptionalValue
is nil, the application will terminate.