Swift guard statement

In this article, you will learn to use guard statement to control the flow of your program's execution.

Swift If Statement describes how you can perform actions based on certain condition (boolean value). In this article, we will explore the benefits of guard statement over if statement to control the program flow and write more simpler and clean code.

Swift Guard Statement

The main use of guard statement is to transfer program control out of a scope on certain conditions. These statements are similar with if statements which executes statements based on certain condition (boolean value) but unlike if, the guard statements only run when certain conditions are not met.

Moreover, statements inside the guard must exit from the scope. Therefore, we have to user program control statements return, break, continue or throw at the end of the guard statement.


Syntax of Guard Statement

guard expression else {
	//statements
	//must contain a control statement:return, break, continue or throw.
}
  • Here, expression is a boolean expression (returns either true or false).
  • If the expression is evaluated to false, statements inside the code block of guard is executed.
  • If the expression is evaluated to true, statements inside the code block of guard are skipped from execution.

How guard statement works?

How Swift guard statement works?

Note: The end of the guard statement must contain a control statement return, break, continue or throw.


Example 1: How guard statement works?

A simple valid guard statement is as below:

guard true else {
	print("Condition not met")
}
print("Condition met")

When you run the program, the output will be:

Condition met

In the above program, guard contains a boolean value true (condition is met). Since, guard statements only run when the condition is not met, the statement inside the guard is not executed. That's why print("Condition met") is executed and outputs Condition met on the screen.

Now let's change the condition to false as:


Example 2: guard statement has to exit the scope

guard false else {
	print("Condition not met")
}
print("Condition met")

In the above program, the guard condition evaluates to false. So, the statement print("Condition not met") inside else should execute. But you will get an error saying 'guard' body may not fall through, consider using a 'return' or 'throw' to exit the scope.

The error message in simple word means, you need to transfer program control from the guard statement using return, break, continue or throw statements. For now we are going to use return. And since return statement can be used only inside a function, we are going to wrap above code in Swift Functions.


Example 3: guard statement inside a function

We can use the guard statement inside in a function in Swift as:

func someFunction() {

	guard false else {
		print("Condition not met")
		return
	}
	print("Condition met")
}

someFunction()
print("Hello after function call")

When you run the above program, the output will be:

Condition not met
Hello after function call

In the above program, the guard condition evaluates to false, therefore the statements inside the guard executes. The first statement print("Condition not met") outputs Condition not met in the console.

And the statement return terminates execution of a function and the statement print("Hello, after function call") after the function call executes which outputs Hello after function call in the console.


Example 4: Guard with optionals

We have seen in Swift Optionals the use of if-let to unwrap an optional. However, we can also use guard statement in place of if-let for unwrapping an optional with one advantage. The main advantage of unwrapping an optional with guard instead of if-let is we can increase scope of the unwrapped variable.

Let's see this in example below:

func changeOptionalStringToUpperCase() {

	var name:String?
	guard let temp = name else {
		print("Name is nil. Cannot process")
		return
	}
	print("Uppercased:\(temp.uppercased())")
}

changeOptionalStringToUpperCase()

When you run the above program, the output will be:

Name is nil. Cannot process

In the above program, you can see the unwrapped value temp is being used outside of the scope defined by guard statement. Since, name is defined optional and contains nil value, the guard statement fails to unwrap the value.

So, the statements inside guard else executes which prints Name is nil. Cannot process in the output and terminates the function with return statement. The equivalent code of the above guard statement if-else statement is:

func changeOptionalStringToUpperCase() {
    
	var name:String?
	if let temp = name {
		print("Uppercased:\(temp.uppercased())")
	} else {
		print("Name is nil. Cannot process")
		return
    }
	//how to access temp here?? Solution:Use Guard
}

changeOptionalStringToUpperCase()

Notice above two statements are both valid and does the same job. But using if-let statement you cannot use the unwrapped value outside of if-let statement. But with guard statement you can use the unwrapped value through out the function.


Example 5: Guard with multiple conditions

Guard statements can also chain multiple conditions separated by comma (,) as:

func changeOptionalStringToUpperCase() {
	var name:String? = ""
	guard let temp = name , temp.count > 0  else {
		print("Name is nil or an empty string. Cannot process")
		return
	}
	print("Uppercased:\(temp.uppercased())")
}

changeOptionalStringToUpperCase()

When you run the above program, the output will be:

Name is nil or an empty string. Cannot process

In the above program ,the guard statement contains two conditions separated by comma.

The first condition let temp = name unwraps an optional which returns true in our case and the second condition temp.count > 0 checks if the unwrapped string has more than 0 characters which evaluates to false in our example.

Therefore, the statement inside guard statement executes statement print("Name is nil or an empty string. Cannot process") which outputs Name is nil or an empty string. Cannot process in the console and terminates the function with return statement.