Open In App

Swift – Guard Statement

Last Updated : 21 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Swift provides a special type of statement referred to as “guard” statement. A guard statement is capable to transfer the flow of control of a program if a certain condition(s) aren’t met within the program. Or we can say, if a condition expression evaluates true, then the body of the guard statement is not executed. In other words, the control flow of the program doesn’t go inside the body of the guard statement. Otherwise, if the condition evaluates false then the body of the guard statement is executed.

Syntax:

guard condition else {

 // body

}

The value of any condition must be of Boolean type. The condition may be an optional binding declaration. When a value is assigned to a variable from an optional binding declaration in a guard statement, the condition can be used for the rest of the guard statement’s enclosing scope.

The else clause of a guard statement is necessary, and must either call a function with the no return type or transfer program control outside the guard statement’s enclosing scope using one of the following statements:

  • break
  • return
  • continue
  • throw

Guard statement in a loop

Guard statements can be used inside a loop. But we use the below control statements only while dealing with a guard statement in a loop,

  • continue: It skips the current iteration at the moment and move to the next iteration if exists.
  • break: It stops the iteration completely and the flow of control comes out of the loop body.

Let us discuss them one by one in detail:

Guard statement with continue control statement:

A guard statement with a “continue” control statement has the following form,

loop {

      // statement 1

     guard condition else {

         // body

        continue

    }

    //  statement 2

}

Here, the loop is one of the loops i.e. for, while 

If the condition expression of the guard statement evaluates true then the body of the guard statement doesn’t get executed and the control flow of the program would directly come at statement 2 and this statement would be executed as soon as the condition expression evaluates true. 

Otherwise, if the condition expression of the guard statement evaluates false then the body of the guard statement gets executed and the control flow of the program goes inside the guard statement and its body will get executed. Since we have used the “continue” statement just after executing all statements of the body hence this “continue” statement also gets executed. Due to this “continue” statement, the current iteration would be skipped at the moment due to which statement 2 would not get executed and the flow control of the program goes to the next iteration if exists.

Example:

In the below program we are iterating from num = 1 to num = 10 using a while loop. We are using a guard statement while the condition expression is “num % 5 == 0”, which simply means that  num is divisible by 5. Now for num = 1, the body of the guard statement would be executed as num is not divisible by 5. On reaching inside the guard statement, firstly num would be incremented by one (now num has become 2) but since we have the “continue” control statement just after it, so the current iteration of the while loop would be skipped at the moment and the next iteration would be executed. This process will repeat itself except when the value of num reaches 5 and 10. In these cases the condition expression evaluates true and the body of the guard statement would be skipped and the flow control of the program would land upon the print statement and the “num” will get incremented by one.   

Swift




// Swift program to demonstrate the working of
// guard statement inside a loop and using
// continue control statement
 
// Initializing variable
var num = 1
 
print("Natural numbers from 1 to 10 which are divisible by 5 are: \n")
 
// Iterating from 1 to 10
while (num <= 10)
{
     
    // Guard condition to check the divisibility by 5
    // If num is not divisible by 5 then execute the
    // body of the guard statement
    guard num % 5 == 0 else
    {
        num = num + 1
        continue
    }
     
    // Print the value represented by num
    print(num)
     
    // Increment num by one
    num = num + 1
}


Output:

Natural numbers from 1 to 10 which are divisible by 5 are: 

5
10

Guard statement with break control statement:

A guard statement with a “break” control statement has the following form,

loop {

      // statement 1

     guard condition else {

        // body

        break

    }

    //  statement 2

}

Here, the loop is one of the loops i.e. for, while. 

If the condition expression of the guard statement evaluates true then the body of the guard statement doesn’t get executed and the control flow of the program would directly come at statement 2 and this statement would be executed as soon as the condition expression evaluates true.

Otherwise, if the condition expression of the guard statement evaluates false then the body of the guard statement gets executed and the control flow of the program goes inside the guard statement and its body will get executed. Since we have used the “break” statement just after executing all statements of the body hence this “break” statement also gets executed. Due to this “break” statement, the iteration would be stopped at the moment due to which the flow control of the program would eventually land upon statement 2, and hence it will get executed.

Example:

In the below program we are iterating from num = 1 to num = 5 using a while loop. We are using a guard statement and the condition expression is “num % 5 != 0”, which simply means that “num” is not divisible by 5. Now for num = 1 to num = 4, the body of the guard statement doesn’t get executed as num is not divisible by 5.  For num= 5 the body of the guard, On reaching inside the guard statement, firstly num would be incremented by one but since we have break control statement just after it, so the while loop would be stopped at the moment and the control flow of the program comes out of the while loop.

Swift




// Swift program to demonstrate the working of
// guard statement inside a loop and using
// break control statement
 
// Initializing variable
var num = 1
 
print("Natural numbers from 1 to 5 which are not divisible by 5 are: \n")
 
// Iterating from 1 to 5
while (num <= 5)
{
 
    // Guard condition to check the divisibility by 5
    // If num is divisible by 5 then execute the body
    // of the guard statement
    guard num % 5 != 0 else
    {
        num = num + 1
        break
    }
     
    // If num is not divisible by 5 then
    // print the value represented by num
    print(num)
    num = num + 1
}


Output:

Natural numbers from 1 to 5 which are not divisible by 5 are: 

1
2
3
4

Likewise, we can achieve the same results by using a for-loop.

Guard statement in a function

Guard statements can be used with a function also. But we use the below control statements only while dealing with a guard statement in a function,

  • return: This stops the execution of the function at the moment and the control flow of the program comes out of the function.
  • throw: This throws an error if something goes wrong and the exception can be caught with the help of a catch block.

Let us discuss them one by one in detail:

Guard statement with a return control statement

A guard statement with a “return” control statement has the following form,

func myFunction (parameters (optional)){

    // statement 1

   guard condition else {

       // body

      return

  }
  //  statement 2
}

// Calling function
myFunction(arguments)

Here, the func is a keyword and myFunction is the function name.

If the condition expression of the guard statement evaluates true then the body of the guard statement doesn’t get executed and the control flow of the program would directly come at statement 2 and this statement would be executed as soon as the condition expression evaluates true.

Otherwise, if the condition expression of the guard statement evaluates false then the body of the guard statement gets executed and the control flow of the program goes inside the guard statement and its body will get executed. Since we have used the “return” statement just after executing all statements of the body hence this “return” statement also gets executed. Due to this “return” statement, the function execution would be stopped at the moment due to which the flow control of the program would eventually come out of the function body.

Example:

In the below program we are checking whether the passed integer, num is divisible by 5 using a guard statement. If the condition evaluates false then the body of the guard statement would be executed that contains a print statement to print, “Not divisible by 5”. the flow of control of the program comes out of the function body at the moment as we have used return statement just after the print statement. Otherwise, the body of the guard would be skipped and the print statement after the end of the guard statement would be executed that prints, “Divisible by 5” to the console.

Swift




// Swift program to demonstrate the working of
// guard statements in a function
 
// Create a function
func checkDivisibilityByfive(num: Int)
{
 
    // Use of guard statement
    guard num % 5 == 0 else
    {
        print("Not divisible by 5")
        return
    }
    print("Divisible by 5")
}
 
// Calling function
checkDivisibilityByfive(num: 5)
 
// Calling function
checkDivisibilityByfive(num: 12)


Output:

Divisible by 5
Not divisible by 5

Guard statement with a throw control statement

A guard statement with a “throw” control statement has the following form,

func myFunction (parameters (optional)) throws{

  // statement 1

 guard condition else {

     // body

   throw error

}
//  statement 2
}


// Calling the function
// Using try and catch block

do {
   try myFunction(arguments)
}

catch {
   print()
}

Here, func is a Keyword, myFunction is the function name, error is the error thrown.

If the condition expression of the guard statement evaluates true then the body of the guard statement doesn’t get executed and the control flow of the program would directly come at statement 2 and this statement would be executed as soon as the condition expression evaluates true.

Otherwise, if the condition expression of the guard statement evaluates false then the body of the guard statement gets executed and the control flow of the program goes inside the guard statement and its body will get executed. Since we have used a “throw” control statement just after executing all statements of the body hence this statement also gets executed. Due to this, the function’s execution would be stopped at the moment by throwing an error, due to which the flow control of the program would eventually come out of the function body. We can handle this error with the help of a do-catch block easily.

Example:

In the below program we are trying to convert the string into its integer equivalent. Firstly, we have tried to convert the string to its integer equivalent with the help of the Int() initializer. Note that passed string can be non-numeric, that’s why we have passed an optional value also (-1). Now if the value of the variable “integerValue” is not equal to -1 then the body of the guard statement will not get executed and the flow control of the program would reach the print statement. Otherwise, if it is equal to -1 then it means that the passed string is a non-numeric string and hence the condition expression of the guard statement will evaluate false and its body will be executed that throws an error that’s one of the cases of the “stringError” enumeration, the function handles the error by printing a message. Otherwise, the function propagates the error to its call site. Now the error is then caught by the catch.

Swift




// Swift program to demonstrate the working of
// guard statement with throw control statement
 
// Enum type for making error message
enum stringError: Error
{
    case non_numeric_string
 
}
 
// Function to convert string to an integer
func convertToInt(myString: String) throws
{
 
    // Using integer initializer
    // If myString is numeric then convert it
    // using initializer Otherwise default type
    // will be assigned that is, -1
    let integerValue = Int(myString) ?? -1
 
    // If integerValue is -1 then guard
    // statement will executed
    guard integerValue != -1 else
    {
        throw stringError.non_numeric_string
    }
     
    // Otherwise this would be printed on console
    print("integerValue:", integerValue)   
}
 
// Try and catch blocks
do
{
    try convertToInt(myString: "12345")
}
catch
{
    print("[X] wrong string format: \(error)")
}
 
do
{
    try convertToInt(myString: "GeeksforGeeks")
}
catch
{
    print("[X] wrong string format: \(error)")
}


Output:

integerValue: 12345
[X] wrong string format: non_numeric_string

Guard having multiple conditions

Guard statements can evaluate multiple conditions separated by commas(,). The body of the guard statement will be executed if at least one condition evaluates false. In other words, if and only if all the conditions evaluate true then in that case the body of the guard statement doesn’t get executed just like logical AND. Otherwise, the body of the guard statement will always get executed. The syntax is given below,

Syntax:

  guard condition1, condition2, ….. else {

    // body

 }

Here, condition 1, condition 2… are condition expressions

Example:

In the below program, we have imposed two conditions for the value of num. num is less or greater than one and num is less than ten. If this condition is not fulfilled then the body of the guard statement would be executed, otherwise, the body of the guard statement would be skipped and the print statement after the guard statement will be executed. 

Swift




// Swift program to demonstrate the working of a
// guard statement having multiple conditions
func checkNumber(num: Int)
{
    guard num >= 1, num < 10 else
    {
        print("\(num) is greater than or equal to 10")
        return
    }
    print("\(num) is less than 10")
}
 
checkNumber(num: 4)
checkNumber(num: 20)


Output:

4 is less than 10
20 is greater than or equal to 10

Guard-let Statement

We can also use guard let-statement. In the below program we have initialized a variable, str as an optional type. In the guard-let statement, we are checking whether “str” contains a value. As str contains a value hence expression evaluates true and the body of the guard-let statement don’t get executed. 

Example:

Swift




// Swift program to demonstrate the working
// of guard-let statement
func checkString()
{
 
    // str is optional type   
    let str: String? = "GeeksforGeeks"
     
    // Check whether myString has a value
    guard let myString = str else
    {
        print("Invalid type")
        return
    }
     
    // Print if condition results into false
    print("myString: \(myString)")
}
 
// Calling function
checkString()


Output:

myString: GeeksforGeeks

Difference between guard and if Statement

The difference between a guard statement and if statement is that for the same condition expression, the body of the “guard” statement is executed if the condition expression evaluates false and the body of an “if” statement is executed if the condition expression evaluates true. Also, in the case of a guard statement, it must have a control statement to change the control flow of the program but it is not mandatory for an if statement.

Example:

In the program, we have created two functions to illustrate the difference between the two. In “checkUsingIf” function, we have used an if statement to check whether the passed string to the function is equal to “GeeksforGeeks”.  If it is so, then the body of the if statement will be executed, and the control flow of the program, will come out of the function body as soon as it reaches the return statement. Otherwise,  the print statement,  print(“GeeksforGeeks and \(myString) are the same.”) will be executed.

In “checkUsingGuard” function, we have used a guard statement to check whether the passed string to the function is not equal to “GeeksforGeeks”. If it is equal, then the body of the guard statement will be executed, and the control flow of the program will come out of the function body as soon as it reaches the return statement. Otherwise, the print statement,  print(“GeeksforGeeks and \(myString) are different.”) will be executed.

Swift




// Swift program to illustrate the difference between
// if and guard statement
 
// Function having if statement
func checkUsingIf(myString: String)
{
 
    // If statement
    if myString == "GeeksforGeeks" 
    {
        print("GeeksforGeeks and \(myString) are the same.")
        return
    }
    print("GeeksforGeeks and \(myString) are different.")
}
 
// Function having guard statement
func checkUsingGuard(myString: String)
{
 
    // Guard statement
    guard myString == "GeeksforGeeks" else
    {
        print("GeeksforGeeks and \(myString) are different.")
        return
    }
    print("GeeksforGeeks and \(myString) are the same.")
}
 
// Calling functions by passing a string as a parameter
checkUsingIf(myString: "GeeksforGeeks")
checkUsingIf(myString: "Bhuwanesh Nainwal")
 
checkUsingGuard(myString: "GeeksforGeeks")
checkUsingGuard(myString: "Bhuwanesh Nainwal")


Output:

GeeksforGeeks and GeeksforGeeks are the same.
GeeksforGeeks and Bhuwanesh Nainwal are different.
GeeksforGeeks and GeeksforGeeks are the same.
GeeksforGeeks and Bhuwanesh Nainwal are different.


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads