Swift Guard Statement

Swift Guard Statement
Swift Guard Bouncer

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:

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:

  1. 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.
  2. 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:

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:

Using guard solves all 3 of the issues mentioned above:

  1. 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.
  2. 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.
  3. 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:

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. 🙂

Discussion

    Vince O'Sullivan on

    Of course, the correct thing to do is to check that your parameters are valid before you call your subroutine aka Design by contract, but this does look like a good way to cover up bad practice. 🙂

    Ray Fix on

    Nice post. I like guard mostly because it keeps the main logic of your function at the top level scope while also supplying bound versions of the optionals you require.

    ecerney on

    @Vince Yes, I agree that if this is your own subroutine making sure you meet all preconditions before making the call could be a nicer approach, but when dealing with APIs that could fail due to reasons you cannot necessarily check for, the guard approach can greatly clean up your code. One way design by contract fails is if you use the method in many different places. If you ever decide to change the precondition, you would need to make changes in multiple locations rather than one.

    @Ray Agreed!

    […] Note: If your’e still confused about why the guard statement is more useful than if-else statements alone, check out Eric Cerney‘s post on Swift guard statement. […]

    peterdev on

    Great post, I couldn’t get my head around it, now it is a lot clearer.

    Steve on

    Seems obvious that checking the condition you want is more readable since if you need to avoid a bunch of conditions you either have to list them all or negate what you want. Both options are less readable than asserting the true condition. I’m not sure I like “guard” as the way to express however, but I guess it’s established nomenclature in the functional world, which is known for pretty obtuse ways of putting things generally.

    Ian on

    What is the difference between guard x > 0 else { return } and if !(x > 0) { return }???

    Very helpful, Thank you!

    Appreciate the focus on one topic and distilling it down with very clear examples of how it is used. Hope you do this will more topics.

    […] Eric Cerney: […]

    Annoymous on

    “guard x > 0 else { return; }” is not as good as “unless x > 0 { return; }”. Why didn’t they just call guard “if”?

    […] You can see more examples and information on guard statements in this article here. […]

    Maury Markowitz on

    I may be missing something important here, so I’d love to hear some comments on this:

    What if a nil is perfectly fine? For instance, in my app I want to play a startup sound, but if that resource is not available, I don’t care, just don’t play it. So the basic syntax would be something like…

    guard let StartSound = (get sound resource from bundle) != nil else {
    //something
    }
    PlaySound(StartSound)
    //do lots of other startup stuff

    Well, that’s not what I want at all. PlaySound will fail in the case that it’s nil, so what, I return out of this method? But I don’t want to return, there’s lots of other code that can still run. So am I supposed to separate out this guard into its own method? But this pattern is all over the place!

    Ok, what am I missing here?

    ecerney on

    Hey Maury, the guard statement should only be used where it makes sense. In the case you just listed, you would use a simple if statement. Guards purpose is for cases where you absolutely want some condition to pass, and if not, exit the current context. :
    if let startSound = (get sound resource from bundle) {
    playSound(startSound)
    }
    //do lots of other startup stuff

    bart on

    You forgot one of the key benefits: The compiler forces you to abort execution in the else statement. You have to return, break, continue, etc. in the else statement (depending on the context) or you’ll get a compilation error. This prevents common bugs where you check for bad input but forget to return if they are encountered.

    John Kountz on

    Vince O’Sullivan — suggest you read the full post on design by contract.

    Where this assumption is considered too risky (as in multi-channel client-server or distributed computing) the opposite “defensive design” approach is taken, meaning that a server component tests (before or while processing a client’s request) that all relevant preconditions hold true, and replies with a suitable error message if not

    Distributed systems can’t rely on the caller having properly vetted inputs, defense in depth is the only safe and reliable way to build such systems.

    John Kountz on

    Excellent example, and very well written.

    thank you!

    […] More on why guard is better than if on Natasha’s blog also in Eric Cerny’s blog. […]

    Suvrat Apte on

    Thanks man!
    I was confused after reading about the ‘guard’ statements. Now I’m quite clear about the concept and use case! 🙂

    Nice article.

    This makes a lot of sense and makes it easier for you to check what you’ve got before you start using it. Being a novice at this it just seems a perfect way to evaluate what you’ve got beforehand.

    Excellent article. look forward to more.

    […] Оригинал статьи Эрика Керни […]

    Tod on

    Great writeup, thanks for sharing this

    […] 원문 링크:  Swift Guard Statement […]

    roi on

    Thanks, it is clear now why the guard function makes the code more readable rather then writing the error handling or so at the end of the function.
    Is it correct to think of guard like an “if-not” statement ?
    for example:
    if-not x >0 then { return}
    or actually:
    if !(x>0) {return}

    Amin Negm-Awad on

    “This is the most basic Objective-C style way[…]
    2. You also need to force unwrap the optional value after the condition fails.”

    I have never done a forced unwrap in Objective-C. So, why it is “Objective-C style”?

    Cristi on

    The only advantage i see is that you don’t indent the code.
    This does not work in a block when you declare [weak self], which makes it useless
    guard let self = self else {
    return
    }

    Chuck on

    The advantage is not just in not indenting the code, it also shows clear intent that it’s a guard condition and not just an undifferentiated ‘if’ statement. It is a bit disappointing that it’s not usable as an expression though, but perhaps in the future, it could steal another feature from Haskell and apply a ‘fail’ function (or more likely method) on the expression’s type rather than make you return by hand every time. (I say “steal” in the most complimentary sense here, BTW).

    So yeah, it’s pretty mild syntax sugar for now, but it could be a placeholder for something better.

    Tushar on

    Very useful. Thanks!

    Please if someone could explain this line in detail .

    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.

    […] Вы читаете перевод статьи Эрика Керни […]

    […] Note: If your’e still confused about why the guard statement is more useful than if-else statements alone, check out Swift team member Eric Cerney‘s post on the Swift guard statement. […]

    […] Statement: The latest version of Swift allows mobile app programmer to use new Guard statements. They can use the Guard statement to check if a particular condition is met and take the […]

    Хороший подарок девушке http://wmbm.ru/ – тут

    […] 使用guard指定某种你希望得到状态而不是检查错误情况之后,使代码更加简洁。 引用 注意 如果你仍然不明白为什么使用guard语句比if-else语句更加有用,请查看Swift团队Eric Cerney‘s post在Swift guard statement。 […]

    […] to know and love the guard statement and the “early return” style of programming; you’re going to see a lot […]

    […] to know and love the guard statement and the “early return” style of programming; you’re going to see a lot […]

    KD Chen on

    Cool. So guard is like security check at the doorstep that makes sure no uninvited guests will get in the party. Love the drawing btw !

    bensy on

    When I capture Image in portrait mode ,the image will rotates horizontally and a black shade will come to the right side of the image, while uploading that image to web view.Help me

Leave a Reply

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