/ ios

I finally get Swift's 'guard' statement.

I finally get Swift's 'guard' statement.

If you are here because you do not understand the guard statement, you have come to the right place. Read on, try to understand it, and if you still don't, tweet me and I will make improvements to this post.


I have been writing Swift 2/3 code for a number of months now. When 2 came out, I converted over my code bases but never decided to learn more about what the language had to offer. One of those new items was the guard statement. I read the docs about it, read some blog posts about it, and no luck. I did not understand it.

Let me explain when to use guard then how to use guard. This is what helped me.

Let's say you are making a game. You have this class UserHighScore that keeps track of the user's current score and also updates it when you need to.

The user's current score right now is nil as the game as not started yet. We don't want to call doubleCurrentScore() before the game has started! Call startGame() in order to reset the user's current score.

class UserHighScore {

    var userCurrentScore: Int?

    func startGame() {
        userCurrentScore = 0
    }

    func doubleCurrentScore() {
        // double current score in here.         
    }

}

Now it's time to write the doubleCurrentScore() function. We need to double the current score that it's set at. Sounds easy, but the userCurrentScore that we are depending on could be nil.

You do not need guard in order to complete this task. In fact, when I didn't understand guard, this was what I wrote:

func doubleCurrentScore() {
    if userCurrentScore == nil {
        return
    }

    userCurrentScore = userCurrentScore! * 2
}

This function works just fine. No guard needed. However, it could be better. I don't like unwrapping (userCurrentScore! <-- the ! symbol after the variable) the userCurrentScore variable after we know it's not nil. I checked for nil, so don't make me force unwrap it.

Here is a better function:

func doubleCurrentScore() {
    if var userCurrentScore = userCurrentScore {
        userCurrentScore = userCurrentScore * 2
    }
}

Great! Better than above. the if statement will only run if userCurrentScore is not nil. And we get to use the unwrapped version of userCurrentScore. Not ! symbol needed.

Now let's rewrite this function again but this time with a guard statement.

func doubleCurrentScore() {
    guard var userCurrentScore = userCurrentScore else {
        return
    }

    userCurrentScore = userCurrentScore * 2 // <-- no ! unwrap needed. The guard statement unwraps it for us.
}

Done. Yes, this function is a couple of lines longer than the previous function we wrote above, but this one is future proof. What if we want to do more operations inside of doubleCurrentScore and use userCurrentScore? The guard statement enforces safety inside of the function. We can now freely use userCurrentScore in the function with no worry of it throwing a nil exception.

Here is what guard does in plain English: "Think of guard like a bodyguard at the club. The bodyguard only lets people in the VIP list go into the club. Once the body guard has enforced everyone in the party is on the VIP list, everyone is safe to start partying." Let's explain the above in code!

class Person {
    var name: String?
    
    init(name: String) {
        self.name = name
    }
    
    func dance() {
    }
}

class Club {
    
    var vipList: [Person] = [Person(name: "Levi"), Person(name: "Betsy"), Person(name: "Emma")];
    
    func comeIntoParty(_ person: Person) {
        guard vipList.contains(where: { (vipPerson) -> Bool in
            return vipPerson.name == person.name
        }) else {
            return
        }
        
        party()
    }
    
    func party() {
        for person in vipList {
            person.dance()
        }
    }
    
}

As you can see, guard is an optional operator that makes your code more readable. This is one reason I love Swift so very much. The language contains some great functionality that allows you to write clean, beautiful, readable code.

Levi Bostian

Levi Bostian

Freelancer building Android and iOS apps for startups. Kotlin, Swift, Vuejs, Nodejs, Docker. Environmentalist, vegan, minimalist. he/him

Read More