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.

  • 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).