Swift Guard vs If: Why the “Bouncer” Beats the “Pyramid”

Lets piggyback off of the previous blog post where I showed you why private(set) was needed to protect your variables. You can read that post here : Using private(set) and why it’s important.

Here is the code that we’re going to be referencing from that tutorial.

struct BankAccount {

var owner:String
private(set) var balance:Double

mutating func depositIntoAccount(amount: Double){

 balance += amount


}


}

We’re going to create a new function to withdraw money from the bank account.

struct BankAccount {

var owner:String
private(set) var balance:Double

mutating func depositIntoAccount(amount: Double){

 balance += amount


}

mutating func withdraw(amount: Double){

balance -= amount

}


}

Now that we have a function to withdraw money from the bank account, let’s call it. I’m running this code in playground.

struct BankAccount {

var owner:String
private(set) var balance:Double

mutating func depositIntoAccount(amount: Double){

 balance += amount


}

mutating func withdraw(amount: Double){

balance -= amount

}


}


var myAccount = BankAccount(owner: "Jim", balance: 200.0)
myAccount.depositIntoAccount(amount: 20)
print(myAccount.balance)


myAccount.withdraw(amount: 201)
print(myAccount.balance)

Open up playground and run this code.

The starting balance is $200 dollar. We deposit $20 dollars and then withdraw $201. Our ending balance is $19 dollars.

We have a serious problem!

What happens if I decided to withdraw $225 dollars instead of $201? The balance would be negative.

We have to put requirements in place before we allow the balance to be changed. We’re going to use swift guard for these requirements because it’s cleaner then multiple if statements. It’s more professional.

Using guard will make your life so much easier. I promise!

Guard may look scary but all it means is that something must be TRUE before the main thing can happen.

If it’s not true then the code under it doesn’t run.

Just like a bouncer at a night club. He guards your age. If your age, you enter the club and if your not you don’t get pass those doors.

Let’s hire a couple of bouncers and give them instructions!

The withdrawal amount has to be greater than 0.
The bank account balance has to be greater than or equal to the withdrawal amount.

guard amount > 0 else {return}
guard balance >= amount else {return}

Add these guards before you change the balance in the withdrawal function.

import SwiftUI
struct BankAccount {

var owner:String
private(set) var balance:Double

mutating func depositIntoAccount(amount: Double){

 balance += amount


}

mutating func withdraw(amount: Double){

guard amount > 0 else {return}
guard balance >= amount else {return}

balance -= amount

}


}


var myAccount = BankAccount(owner: "Jim", balance: 200.0)
myAccount.depositIntoAccount(amount: 20)
print(myAccount.balance)


myAccount.withdraw(amount: 201)
print(myAccount.balance)

If both of these guard are TRUE the withdrawal will occur. Lets add a few print statements to
these guards and withdraw some money!

struct BankAccount {

var owner:String
private(set) var balance:Double

mutating func depositIntoAccount(amount: Double){

 balance += amount


}

mutating func withdraw(amount: Double){

guard amount > 0 else {
print("Amount needs to be positive")

return}
guard balance >= amount else {

print("Insufficient funds")
return}

balance -= amount
print("Success! Remaining balance: \(balance)")

}


}


var myAccount = BankAccount(owner: "Jim", balance: 200.0)
myAccount.depositIntoAccount(amount: 20)
print(myAccount.balance)


myAccount.withdraw(amount: 800)
print(myAccount.balance)

Now try to withdraw $800 and see if you can! Guard doesn’t allow this to happen and if you were to try and accomplish this with multiple if statements your code would be messy and who wants to fall into the category of pyramid doom.

Use guard for preconditions, when the condition must be true for the rest of the function to work.

Use IF when there are two or more valid paths and the function can continue either way it goes.

The output of trying to withdraw 800 is below

220.0
Insufficient funds
220.0


This is part of my daily Swift notes on writing safer, more predictable code.

Check out my notes on error handling using enums : Stop Guessing Why Code Fails: Using Swift Enums for Detailed Error Handling. In this blog post, I will show you how to add error handling to the BankAccount using enums and do-try-catch.

Master Swift, One Tip a Day

Join other developers getting one bite-sized Swift lesson delivered to their inbox every morning.

🚀 Awesome! Check your inbox for your first tip.
Something went wrong. Try again.

2 thoughts on “Swift Guard vs If: Why the “Bouncer” Beats the “Pyramid””

  1. Pingback: Using private(set) and why it’s important – Swift Owls

  2. Pingback: Stop Guessing Why Code Fails: Using Swift Enums for Detailed Error Handling – Swift Owls

Leave a Comment

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

Scroll to Top