The Swift guard statement


While the guard and the if statement seem very similar at first look, they serve distinct purposes. The guard statements simplifies writing code with early exits and avoids the pyramid of doom. The syntax for writing the guard statement is as follows:

guard condition else { //clean up and leave exit scope } //further code.

If the condition evaluates to false, the else block is executed.
Within the else block execution must exit the enclosing scope. This means that you must return or throw an error or take some action to exit your scope in the else block.

Guards let you program in a more linear fashion without a lot of nesting, because it is the failure cases that are enclosed in a block rather than the success case. In the following contrived example we have an openfile() function that returns an Optional(File) object and a writeFile() function that returns an Optional(UInt) object representing the number of bytes written.

Opening the file and writing to it using traditional if statements would look something like this:

if let f = openFile(‘filename’) { 
  if let bytesWritten = writeToFile(f, content) { 
    //more operations 
  } else { 
} else { throw(FileOpenError) }

Guard statements allow you to avoid nesting and writing much more linear and readable code:

guard let f = openFile(‘filename’) else { throw(FileOpenError) } 
guard let bytesWritten = writeToFile(f, content) else { throw(FileWriteError) } 
//more operations

One advantage of guard statements that becomes immediately obvious is because there is a lack of nesting, the return values of the function calls are available outside of nested scopes. If there were more conditions to check, the code using the if statements would become much more complicated due to more and more levels of nesting. This can be completely avoided with guard statements.

Think of the guard statement of guarding the rest of the code in its scope from being accessed unless its condition evaluates to true.

So when can you use a guard statement instead of an if statement?
if statements can only be equivalently replaced by guard statements in either one of the following cases.

  • The if-let block would contain the rest of the function. That is, there is no more code after the if block.

  • The else block of the if-else statement would return or throw an error or perform any other action that would result in leaving the enclosing scope.