When I first saw the Swift guard statement during Apple’s Platform State of the Union, I couldn’t quite understand why I would ever use it. So what is it? The tl;dr is as follows:

Like an if statement, guard executes statements based on a Boolean value of an expression. Unlike an if statement, guard statements only run if the conditions are not met. You can think of guard more like an Assert , but rather than crashing, you can gracefully exit.

Even after seeing some examples, I only saw it as a confusing way to accomplish what we already could with Optional Binding or with if-else statements alone.

It wasn’t until I started discussing it over this Twitter conversation that I realized there are actually some interesting benefits of using such syntax.

Diving In

Let’s take a simple example comparing current techniques vs using the new guard statement:

1 2 3 4 5 6 7 8 9 func fooManualCheck ( x : Int ? ) { if x == nil || x <= 0 { // Value requirements not met, do something return } // Do stuff with x x ! . description }

This is the most basic Objective-C style way to make sure a value exists and that it meets a condition. Now this works fine, but has a couple flaws:

You’re checking for a condition that you don’t want, rather than checking for the value you do want. Code becomes confusing when you have a bunch of checks like this. What you’re hoping for here is that your condition actually doesn’t pass. You also need to force unwrap the optional value after the condition fails.

Swift gave us a way to clean this up and fix some of these flaws through Optional Binding:

1 2 3 4 5 6 7 8 func fooBinding ( x : Int ? ) { if let x = x where x > 0 { // Do stuff with x x . description } // Value requirements not met, do something }

This removes both of the flaws that the first function had, but adds a new one. Here you’re putting your desired code within all the conditions, rather than afterward. You might not immediately see a problem with this, but you could imagine how confusing it could become if it was nested with numerous conditions that all needed to be met before running your statements.

The way to clean this up is to do each of your checks first, and exit if any aren’t met. This allows easy understanding of what conditions will make this function exit.

I’ve heard this called the Bouncer Pattern, which makes a lot of sense. You want to get rid of the bad cases before they get in the door. It also allows you to think about one case at a time, rather than figuring out how all combinations need to work together.

Here enters the guard statement:

1 2 3 4 5 6 7 8 9 func fooGuard ( x : Int ? ) { guard let x = x where x > 0 else { // Value requirements not met, do something return } // Do stuff with x x . description }

Using guard solves all 3 of the issues mentioned above:

Checking for the condition you do want, not the one you don’t. This again is similar to an assert . If the condition is not met, guard ‘s else statement is run, which breaks out of the function. If the condition passes, the optional variable here is automatically unwrapped for you within the scope that the guard statement was called – in this case, the fooGuard(_:) function. This is an important, yet notably strange feature that really makes the guard statement useful. You are checking for bad cases early, making your function more readable and easier to maintain.

The cool thing is that this same pattern holds true for non-optional values as well:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 func fooNonOptionalGood ( x : Int ) { guard x > 0 else { // Value requirements not met, do something return } // Do stuff with x } func fooNonOptionalBad ( x : Int ) { if x <= 0 { // Value requirements not met, do something return } // Do stuff with x }

Wrapping Up

I hope this simple example shows how you could start using guard immediately in your Swift code to make your function/methods more clear. It’s easy for us to immediately judge the value of a new feature until you give it a chance and see what it can or can’t do for you.

Going from Objective-C to Swift is a huge change, not only to syntax, but how you have to look at architecting your code. You can only benefit from this awesome new language if you actively change your mindset while writing code by expanding your everyday patterns and style.

If you find anything else interesting let me know, this syntax is brand new to me too. 🙂