Over a million developers have joined DZone.

Control Structures and Optionals in Swift (Part II)

In the first part of this series, we discussed optional chaining and immediate evaluation. Today, we're going to touch on the other two optional access methods.

· Mobile Zone

Visually compose APIs with easy-to-use tooling. Learn how IBM API Connect provides near-universal access to data and services both on-premises and in the cloud, brought to you in partnership with IBM.

If let ... where ... else ... 

So, we have some guidelines on when to use optional chaining (which is essentially never). What about if let... Statements?

So if let... And guard ... statements are very powerful ways to extract values from optionals and to allow you to both limit optional exposure and write cleaner code. Both statements allow you to use where clauses so you can avoid the conditional pit of doom (or pyramid of doom, but it always looked more like a pit to me) via seemingly unending if statements.

So, let’s take a closer look at ‘if let....

var intOpt: Int?
intOpt = 5

if let myInt = intOpt where myInt > 4 && myInt < 6
	print("My int! \(myInt)")
} else {
	print("no dice.")

Here, if intOpt is not 5 or if it’s nil, the control structure will print no dice. This is really cool. You can include an arbitrarily detailed boolean expression in the where clause, you limit your optional exposure to the if... block, and you can have an alternative action if the value hasn’t been set. Very clean, no conditional stacking, and your optional value is contained. Any code associated with this construct, in either the if or else block will not fail because of a null condition. Very nice.

Guard statements are even more useful.

Guarding Execution

So guard statements are designed to be used within functions. They’re designed to allow you to fail fast or return early if you don’t have what you need to successfully execute a chunk of code.

Let’s take a look:

func iAmGuarded(value: Int?) {
	guard let myValue = value where myValue > 4 && myValue < 6 else {
	print("value: \(myValue)")

var value: Int?

value = 5
value = 7

So, of these three calls to iAmGaurded:, only one will execute. The second.

This is even better than if let...! We can unwrap optionals at the beginning of the function, assign values according to defined conditions in the where clause, and if things aren’t really how we want them, we can just return. No mess, nice and clean.

We can even do this with multiple arguments:

func doubleGuard(value: Int?, value1: Int?) {
	guard let myVal = value, myVal1 = value1
	where myVal > 2 && myVal1 > 3 else {
	print("Sweet doubletime! \(myVal) \(myVal1)")

var val, val1: Int?
doubleGuard(val, value1: val1)
val = 1; val1 = 2
doubleGuard(val, value1: val1)
val = 3; val1 = 4
doubleGuard(val, value1: val1)

Nice! We can define all our execution conditions at the beginning of the function. Programming by contract anyone?

Wrapping It All Up

So that’s optional unwrapping in a nutshell. If nothing else, remember, avoid ! and ?, use if let.... If you don’t want to exit a function, and use guard... If you want function control. All in all, use guard... preferably, and fallback to if let.... This has been treating me well so far, I think it’ll work as well for you. Happy Swifting!

The Mobile Zone is brought to you in partnership with Strongloop and IBM.  Visually compose APIs with easy-to-use tooling. Learn how IBM API Connect provides near-universal access to data and services both on-premises and in the cloud.


The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}