Swift: When to use guard vs if

One thing I’ve noticed recently in my code-base is that I tend to default to guard vs if. In fact, whenever I write an if statement, I facepalm myself and change it to a guard without thinking much.

But that’s become a problem. There is in fact a difference between guard and if and thought does need to be put into which one to use.

The difference is a bit subtle, but it is there. guard should be used when certain values are expected to be present for the function to execute as intended.

For example, in the try! Swift app, when it displays a presentation session type, the presentation title is the session title.

However, not every session has a presentation, so the presentation is optional. However, for this specific session type, it is expected that a presentation is in fact present and that it has a title. This is a perfect use-case for guard!

The talk title should always be present for a presentation session type. If it’s not there, it’s a fail. This is why we use guard in this case.

However, consider another case. A Coffee Break session could be sponsored. In that case, the title of the coffee break should include the sponsor name. Both are correct – if there is a sponsor, we include the name of the sponsor, but if there isn’t one, we don’t include it. This is the type of case where if should be used:

So as @ecerney puts it so well, think of guard as a lightweight Assert:

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.

So think if before you guard!

Enjoy the article? Join over 17,500+ Swift developers and enthusiasts who get my weekly updates.

  • MJLangford

    For this example, it makes a lot of sense to move all the decision making into the top level switch statement with multiple case statements, using pattern matching (or if you insist, nested switch statements).

    This will greatly lessen the indentation and make tracing the code simpler.

    Many places people used to reach for “if”, and especially “if/else if/else” statements, are made safer with the Switch statement in Swift.

    Switch used to be a pit of errors in Objective-C and C. It is one of the safest control structures in Swift and makes very readable code with very little unwrapping ceremony.

    • I think it’s overkill to use the switch statements if there is only one condition, but if there are two, then pattern matching is better.

      • arbi dh

        I used to use if lets a lot but guard made it real simple and the variable is exposed in the whole block. I don’t look at if’s as guards but when i want to use if let I tend to use guard. Thank you for this great post. I am a beginning blogger and I am interested in best design patterns in mobile. I also am interested in learning clean coding and best separation of responsibility without complicating the code. My blog is at http://www.code-ios.com

  • Mohamed

    Thanks. Really like what you said, it’s a lightweight assert, to make it better perhaps it’s good to add a precondition preconditionFailure into your failed guard…

    Additionally, a deeper comparison: http://stackoverflow.com/a/39263210/5175709

    • I agree with doing some kind of precondition or return normally, but in this case, there was an alternative value that wasn’t great, but works well enough for the data.

  • John Estropia

    Good tip, thanks 🙂

    Another thing that helps me decide wether to use if or guard is to consider how long the if and else blocks are. If the else block is relatively shorter, then guard is a very good construct to reduce nesting and indentation.

  • loki

    or simply ‘return presentation?.localizedTitle ?? defaultTitle’

  • TheCodingArt

    I think a far better explaination is tied to why guard was introduced. The golden path is a fairly well defined standard, use it when you can.

  • soniccat

    Prefer not to use guard at all because, first of all, it forces to write more than one return statement. It’s easier to understand small functions with only one. Then guard forces to handle wrong cases with early exits which might be wrong and should be done in another place.

    In above examples, I think it would be better to move presented case blocks to separate functions. Where each function has one if statement and one return statement.

  • J-2

    I also learnt that “If let” will not work if the parameter or value is missing, the value is empty, use “guard” to catch empty value.

  • Mohammed M. Ennabah

    I use guards only when validating something, do you think there is any further recommended usage?

  • Abhishek Bedi

    The beauty of can be seen when we eliminate all unexpected/incorrect inputs and just focus on on the purpose. comes in handy when we have alternative ways of handling inputs rather than just bailing out (for which is the best).

  • Bob R.

    Regarding if, if let, guard, and switch statements, I’ve come up with a rule of thumb that works for me, possibly for others.

    I use guard statements as above, when I need values to be present for a function to perform correctly. Since a lot of Swift is working with optionals those values are checked at the first method they will be used in. Most of the time this occurs in the method where I start returning values. The first thing I do is check if those values exist before I start creating any variables scoped to the method, this saves me from allocating and deallocating memory needlessly.

    I use if let when I come across a part of a function that I don’t really care if it returns a value from an optional, kind of like, hey it’s cool if you can give me a value but I’m not worried if you can’t, I can handle it. These are used wherever I have optionals when I still want the method to perform a task/return a value.

    NOTE: while I could use the nil coalescing operator (??) I choose not to, I read in a few places that it is a compiler optimization if you don’t use it. That being said, I don’t take it out of my swift vocabulary, I only tend to use this when code readability outweighs compiler optimizations. (e.g. 20 if let statements in a row vs 20 ?? in a row)

    I use switch statements whenever the body of a complete switch statement (including a single case, the default case, and both breaks and braces) are shorter than the length of the if statements (combined) that I will be creating; or about 3 if statements. I also would rather use a switch statement when dealing with enums with more than a single value than I would if statements as long as the enum makes sense to switch on the case.

    I use if statements for everything else, mostly this just ends up being stuff like:
    if object.count > 0 { someFunctionThatRequiresThisData() }
    else {
    //load this necessary data now (synchronously)
    someFunctionThatRequiresThisData()
    }
    or
    if CLLocation.authorizationStatus() == .authorizedWhenInUse { // get the location }
    else { locationManager.requestAuthorization() }