The Value of guard in Swift

Most everyone reading will have used if statements regardless of the language you were programming in prior to Swift. This post will look at what some call the pyramid of doom that can occur from if statements, and then we’ll look at how to avoid it with the guard statement.

Swift 2.0 introduced guard, and it is just what the name says. Think of guard as that guy at the door that will only let you into the party once he has checked that you have an invite, you are of age, and you have not had too many beverages already. Once you pass all the checks, you are successful and can reach your intended destination inside the party.

For this example, we will consider a fictitious library that has a collection of books, and members that wish to borrow the books.

Since Book is essentially a bag of attributes, we’ll use a struct and define it as follows:

We’ll also define a struct for Member, and define it as follows:

Finally, before we create the library to manage books and members, we need an enum for possible errors that may occur when members attempt to borrow books.

For this fictitious example of a library, there will be a minimum age for each book in order for a member to borrow the book, in addition to other usual validations that must be considered.

The Library class will have books, and members that can borrow the books. In the class definition for the library, we’re going to start out assuming that we do not have a guard yet, and we’ll define a method to borrow a book from the library without this lovely new feature of Swift, so that we can then contrast it with how much nicer it is having a guard at the front door.

Without our very well trained guard at the door of the library, you can see that things are a bit chaotic, represented by all the nested if statements. This does not look pretty.

For every validation check that we want to perform, we need another else statement for when the check fails. To arrive at the point where a member is permitted to borrow a book, there is now a hierarchy and unfortunately the success path for borrowing a book is buried inside this hierarchy.

We can definitely do better than that. Enter the new guard that has been hired by Swift to clean things up and define a better way to borrow a book. This is the new method implemented with the guard statement.

When guard is used, the variable or constant in the condition is available for the rest of the code block that the guard statement appears in. In this example it means that member and book are available in the borrowBook method once they are defined. Once the validation is completed, the count of a given book is decremented and the book is loaned to the member.

Take a look at the cleanliness of this code, where each validation check is done and when all are complete, control reaches the success path.

It can be tested with the code below.

In this case, Billy is not old enough to borrow the Swift 2.0 book, so the error would be caught and “Member is too young for the book.” would be printed.

The guard statement is a welcome and very important feature of Swift. It makes code easier to read and understand, and therefore the code is safer and more maintainable.

The playground file for this example is available in my SwiftNotes project in GitHub.

Leave a Comment: