What are Optionals in Swift? – Donny Wals

What are Optionals in Swift? – Donny Wals


In an earlier article, I defined how variables are outlined in Swift utilizing let and var. Each constants (let) and variables (var) in Swift all the time have a sort; it is what makes Swift a strongly typed language.

For instance, we may outline a String variable like this:

// the compiler will know myString is a String
var myString = "Hiya, world"

// we're explicitly telling the compiler that myString2 is a String
var myString2: String = "Hiya, world"

This fashion of defining variables makes a number of sense when it is doable to instantly assign a worth to our variable.

Nevertheless, generally you may write code the place it isn’t doable to assign a worth to your variable instantly. Otherwise you’re working with features that will or might not be capable to return a sound worth.

In Swift, we name values that may distiguish betwene having a worth and never having a worth an Elective. Earlier than we dig too deeply into how we work with optionals, let’s discover the distinction between “no worth” and “default” worth in order that we perceive precisely why optionals exist within the first place.

The distinction between a default worth and no worth

In programming, working with an idea known as null or as Swift calls it nil will typically imply {that a} variable or a perform’s return worth could be “nothing”. There’s a number of technical baggage surrounding the terminology however with a purpose to set up a superb working data, we cannot dig into that too deeply.

The necessary factor to grasp right here is that defining an empty String like this: var myString = "" defines a String with a default worth. The worth is empty however the var myString is holding on to some knowledge that may signify an empty String. Usually it is a completely advantageous alternative.

Now let’s contemplate a distinct instance the place a default worth could be lots tougher to outline.

var theUser: Consumer = ???

Our Consumer object cannot be created with out enter from different sources. And this enter won’t be current at the moment that we outline our variable. We’ll want a technique to outline this var theUser with no knowledge moderately than a default worth.

An actual world analogy you may consider is the next. While you sit down at a restaurant for some drinks, you’ll initially haven’t any glasses or cups in your desk. Because of this, your waiter will know that you have not been served something in any respect so that they’ll know to go over and hand you a menu, introduce themselves and see whether or not they can take any orders. As soon as you’ve got been served you may need some empty glasses in your desk. The waiter will now know to ask to refill or take a distinct order.

This can be a demonstration of how no worth (no glass on the desk) and an empty worth (empty glasses on the desk) can have vital variations in that means they usually cannot all the time be used interchangeably.

In Swift, we specific the power of a property having no worth moderately than a default worth by defining an elective Consumer object:

var theUser: Consumer?

The ? after our Consumer tells the compiler that var theUser will both include a worth of kind Consumer or it’ll maintain nothing in any respect (we name this nil).

It is good to know that the ? is a extra handy to jot down the next:

var theUser: Elective

Whereas the 2 methods of defining theUser do the identical factor, it is best follow to jot down var theUser: Consumer?. It is simpler to learn and sooner to jot down.

Word that every one sorts in Swift could be written as an elective. For instance, when you’re defining a String which may have to be initialized as “no worth” you can write: var theString: String?.

The primary distinction between “no worth” and “default worth” is commonly whether or not there’s any semantic that means to pointing at nothing or pointing to a default worth. For instance, an elective Bool (Bool?) virtually by no means is smart; in most eventualities it is possible for you to to choose a wise default worth that is secure to make use of. In different instances, one thing being empty or lacking may point out that enter from the person is required, or that it’s essential to fetch knowledge from an exterior supply and it isn’t doable or cheap to offer a default worth.

Now that you know the way to jot down elective properties, let’s have a look at how optionals are utilized in Swift.

Utilizing optionals in your code

As soon as you’ve got outlined an elective worth in Swift, it is necessary that we deal with the opportunity of a worth being nil in addition to the worth being non-nil. Swift is fairly strict about this so optionals aren’t utilized in the identical method as you’ll use regular variables or constants.

For instance, if we contemplate the theUser variable from earlier, we will not learn the identify from this property like this:

var theUser: Consumer?

// Worth of elective kind 'Consumer?' should be unwrapped to confer with member 'identify' of wrapped base kind 'Consumer'
print(theUser.identify)

The Swift compiler will inform us that we have to “unwrap” worth of elective kind Consumer? with a purpose to entry its member identify. That is the compiler’s method of telling us that theUser might or will not be nil so we have to deal with each eventualities.

Let’s check out severals methods through which we are able to “unwrap” our elective.

Unwrapping with if let

If we’re writing code the place we wish to solely execute part of our script or perform in case the worth is not nil, we are able to use one thing known as an if let unwrap. Here is what that appears like:

var theUser: Consumer?

// elsewhere within the code...
if let userValue = theUser {
  print(userValue.identify)
} else {
  print("the person is nil")
}

This if let makes an attempt to learn theUser and we assign it to a continuing. This fixed is then made obtainable within the if’s physique the place we all know that userValue is of kind Consumer. Outdoors of our if physique we cannot be capable to entry userValue; it is solely made obtainable within the if. As wanted, we are able to present an else to deal with eventualities the place theUser is nil.

Word that the code above might be simplified a bit. Swift permits us to make use of one thing known as a shadow variable (variable of the identical identify) for theUser which might change the if let as follows:

var theUser: Consumer?

// elsewhere within the code...
if let theUser {
  print(theUser.identify)
} else {
  print("the person is nil")
}

Word that theUser within the if physique just isn’t the identical variable as theUser exterior of the if physique; it is a completely different property with the identical identify. For that cause, theUser within the if physique is of kind Consumer and outdoors of the if physique it is Consumer?. This function of Swift is sweet if you’re accustomed to optionals however I discover that generally it is higher to offer a distinct identify in order that it is clear if you’re utilizing your unwrapped property or if you’re utilizing your elective property.

Unwrapping optionals with guard let

Whereas if let is nice for utilization within code the place it does not matter that a lot whether or not a worth is or is not nil, you generally wish to make it possible for a worth is not nil in the beginning of a perform. With if let this could typically imply that you just write an if let in the beginning of your perform after which write the entire perform physique within your if let:

func performWork() {
  if let unwrappedUser = theUser {
    // do the work
  }
}

This works however it will probably result in a number of nested code. For eventualities the place you solely want to proceed in your perform if a worth just isn’t nil, you should use guard let as an alternative:

func performWork() {
  guard let unwrappedUser = theUser else {
    return
  }

// do the work
// unwrappedUser is accessible to all code that comes after the guard
}

A guard permits us to make sure that our person has a worth and that the unwrapped worth is accessible to all code that comes after the guard. After we’re utilizing a guard we should present an else clause that exits the present scope. Normally which means that we put a return there with a purpose to bail out of the perform early.

Unwrapping a number of properties

Each if let and guard let enable us to unwrap a number of properties directly. That is accomplished utilizing a comma separated record:

if let unwrappedUser = theUser, let file = getFile() {
  // now we have entry to `unwrappedUser` and `file`
}

The syntax for guard let is similar however requires the else:

guard let unwrappedUser = theUser, let file = getFile() else {
  return
}

  // now we have entry to `unwrappedUser` and `file`

Word that writing your code like this may require all unwraps to succeed. If both our person or file could be nil within the instance above, the if physique would not be executed and our guard would enter its else situation.

Studying by way of elective chaining

While you’re working with an elective and also you’d wish to get entry to a property that is outlined in your object, you can write an if let after which entry the property you are inquisitive about. You noticed this earlier with Consumer and its identify property:

if let theUser {
  print(theUser.identify)
}

If we all know that we’re solely within the identify property we are able to use a way known as elective chaining to instantly entry the identify property and assign that to the property we’re writing the if let for as an alternative.

Here is what that appears like

if let userName = theUser?.identify {
  print(userName)
}

That is very handy after we’re in a state of affairs the place we actually solely care a couple of single property. If both theUser is nil or (if identify is elective) identify is nil the if physique will not be executed.

We are able to use this system to entry bigger chains of optionals, for instance:

if let division = theUser?.division?.identify {

}

Each theUser and division are optionals and we are able to write a sequence of entry utilizing ? after every elective property. As soon as any of the properties within the chain is discovered to be nil the chain ends and the result’s nil.

For instance, if we simply assign the chain from above to a property that property is a String?

// division is String?
let division = theUser?.division?.identify

The identify on the division property does not need to be a String? however as a result of we’re utilizing elective chaining we’ll get a nil worth if both theUser or division is nil.

This leads me to at least one final technique that I would advocate for working with and that is utilizing the nil coalescing operator.

Unwrapping optionals utilizing nil coalescing

For any elective in Swift, we are able to present a default worth inline of the place we entry it. For instance:

let username: String?

let displayName = username ?? ""

The ?? operator within the instance above known as the nil coalescing operator and we are able to use it to offer a default worth that is utilized in case the worth we’re attempting to entry is nil.

That is significantly helpful when it’s essential to present values to render in a person interface for instance.

You can even use this system together with elective chaining:

// division is String
let division = theUser?.division?.identify ?? "No division"

Now, let’s check out one final technique to unwrapping that I am solely together with for completeness; this method ought to solely be used as a final resort in my view.

Drive unwrapping optionals

For those who’re 100% completely positive that an elective worth that you just’re about to entry can by no means be nil, you may pressure unwrap the elective when accessing it:

print(theUser!.identify)

By writing an ! after my elective variable I am telling the compiler to deal with that property as non-optional. Because of this I can simply work together with the property with out writing an if let, guard let, with out elective chaining or with out utilizing nil coaslescing. The key draw back right here is that if my assumptions are mistaken and the worth is nil in any case my program will crash.

For that cause it is virtually all the time most popular to make use of one of many 4 secure approaches to unwrapping your optionals as an alternative.

Leave a Reply

Your email address will not be published. Required fields are marked *