Swift Guard Statements Explained

A guard statement is as simple as using an if..else statement and has its own benefits and uses. Learn how to use Swift guard statements in this tutorial!
Written by

Chris C

Updated on

Nov 29 2024

Table of contents

    Swift has lots of cool features that help the budding developer write great code that is safe and readable at the same time.

    Swift Guard

    What is Swift Guard?

    A guard statement is as simple as using an if..else statement and has its own benefits and uses. Swift guard is defined as a statement that is used to transfer program control out of a scope if one or more conditions aren’t met.

    What it means is that it is essentially a redirection or early exit of a statement or function to prevent crashing and incorrect data. Guard is commonly used inside a function, closure or loop.

    If..else versus guard

    To better explain guard lets have an example where we compare it to the more familiar if..else. Lets take for example a for loop that will print even numbers:

    // Using the if..else
    
    for i in 1...20{
        if(i.isMultiple(of: 2)){
            print(i)
        }
    }
    

    Guard works like a reverse if..else, so it works like guard based on [condition] if it’s true then move on and continue the loop, else do something to catch possible error.

    //Using guard
    
    for i in 1...20{
        guard i.isMultiple(of: 2) else {
           //don’t run anymore codes and  just continue to the next index
            continue
        }
        print(i)
    }
    
     // BOTH codes will print even numbers (2,4,6,8,10,12,14,16,18,20)
    

    Notice that we used continue, this is one of the possible control options when handling a guard statement. Here is a list of the others:
       

    return, to exit a function or closure
    break, to exit a loop like for
    continue, to continue to the next loop iteration
    throw, to exit a function and throw an error value
    

    So if both codes print the same why would you use guard in this case? The answer is because if you remember guard is an early exit this means that when the condition is not met it will redirect the scope inside of the guard, thus, it does not continue to execute the code outside of the guard statement (in our case the “print(i)”), this means that theoretically, it would be faster and wont consume as much resources in running the loop because it already exited/cancelled before anything else is executed.

    Handling possible errors

    Let’s say we have a function called submit that will take info from our registration page and submit it to the server.

    func submit() {
        guard let username = usernameField.text else {
            print(“username is blank”)
            return
        }
    
        guard let password = passwordField.text else {
            print("password is blank")
            return
        }
    
        guard let email = emailField.text else {
            print("email is blank")
            return
        }
    
        registerUser(username, password, email)
    }
    

    In Swift if you try to take the text value of a UITextField that is blank you will be getting a nil. This makes it unusable in most cases and would cause your program to crash.

    If you notice this function will check if username, password, and email is blank, it also won’t waste resources if on first call the name or password is blank then there is no need yet to check the other values, it also won’t call the registerUser function if the conditionals are not met.

    What’s more is that it is easier to read than your typical if..else statement as the same logic will result in a function that looks like this:

    func Submit() {
        if let username = usernameField.text {
            if let password = passwordField.text {
                if let email = emailField.text {
                    registerUser(username, password, email)
                } else {
                    print("email is blank")
                }
            } else {
                print("password is blank")
            }
        } else {
            print("username is blank")
        }
    }
    

    Imagine if there are even more fields, it will result in a landmine of brackets and if..else’s that is very confusing to read.

    Multiple conditions

    Guard is capable of testing additional conditions even if the initial condition is true, this in turn eliminates the need to create if..else statements after your initial guard,  to test the field you just need to use the where functionality. Let’s take for example a better password checker:

    guard let name = passwordField.text where password.characters.count > 7 else {
        print("password must be at least 8 characters long")
        return
    }
    

    Conclusion

    As you can see guard has a multitude of uses, especially in error catching and readability. There are times that the ever handy if..else is enough for basic needs but with this short look into guard statements it should make your coding more fun and readable. Happy coding 🙂


    Further Reading




    Get started for free

    Join over 2,000+ students actively learning with CodeWithChris