📜  Swift – 守卫声明

📅  最后修改于: 2022-05-13 01:55:11.961000             🧑  作者: Mango

Swift – 守卫声明

Swift 提供了一种特殊类型的语句,称为“guard”语句。如果程序中不满足特定条件,则保护语句能够转移程序的控制流。或者我们可以说,如果条件表达式的计算结果为真,则不执行保护语句的主体。换句话说,程序的控制流不会进入保护语句的主体。否则,如果条件评估为假,则执行保护语句的主体。

句法:

任何条件的值都必须是布尔类型。条件可以是可选的绑定声明。当一个值从一个保护语句中的可选绑定声明分配给一个变量时,该条件可以用于保护语句的封闭范围的其余部分。

保护语句的 else 子句是必要的,并且必须调用具有无返回类型的函数或使用以下语句之一将程序控制转移到保护语句的封闭范围之外:

  • 休息
  • 返回
  • 继续

循环中的保护语句

Guard 语句可以在循环中使用。但是我们仅在处理循环中的保护语句时使用以下控制语句,

  • continue:当前跳过当前迭代,如果存在则移动到下一个迭代。
  • break:完全停止迭代,控制流从循环体中出来。

让我们一一详细讨论:

带有 continue 控制语句的 Guard 语句:

带有“继续”控制语句的保护语句具有以下形式,

loop {

      // statement 1

     guard condition else {

         // body

        continue

    }

    //  statement 2

}

这里,循环是循环之一,即for,while

如果保护语句的条件表达式为真,则保护语句的主体不会被执行,程序的控制流将直接进入语句 2,并且一旦条件表达式为真,该语句就会被执行。

否则,如果保护语句的条件表达式计算为假,那么保护语句的主体将被执行,程序的控制流进入保护语句内部,其主体将被执行。由于我们在执行主体的所有语句之后使用了“继续”语句,因此这个“继续”语句也被执行。由于这个“继续”语句,当前的迭代将被跳过,因为语句 2 不会被执行,如果存在,程序的流控制将转到下一个迭代。

例子:

在下面的程序中,我们使用 while 循环从 num = 1 迭代到 num = 10。当条件表达式为“num % 5 == 0”时,我们使用了一个保护语句,这仅仅意味着该 num 可以被 5 整除。现在对于 num = 1,保护语句的主体将被执行,因为 num 不是可被 5 整除。在到达保护语句内部时,首先 num 将增加 1(现在 num 已变为 2),但由于我们在其后有“继续”控制语句,因此将跳过 while 循环的当前迭代此刻,下一次迭代将被执行。这个过程会重复自己,除非 num 的值达到 5 和 10。在这些情况下,条件表达式的计算结果为 true,并且将跳过保护语句的主体,程序的流控制将落在 print 语句和“ num”将加一。

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
}


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
}


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)


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)")
}


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)


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()


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")


输出:

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

5
10

带有中断控制语句的 Guard 语句:

带有“break”控制语句的保护语句具有以下形式,

loop {

      // statement 1

     guard condition else {

        // body

        break

    }

    //  statement 2

}

这里,循环是循环之一,即for、while。

如果保护语句的条件表达式为真,则保护语句的主体不会被执行,程序的控制流将直接进入语句 2,并且一旦条件表达式为真,该语句就会被执行。

否则,如果保护语句的条件表达式计算为假,那么保护语句的主体将被执行,程序的控制流进入保护语句内部,其主体将被执行。由于我们在执行主体的所有语句之后使用了“break”语句,因此这个“break”语句也被执行。由于这个“break”语句,迭代将在此时停止,因此程序的流控制最终将落在语句 2 上,因此它将被执行。

例子:

在下面的程序中,我们使用 while 循环从 num = 1 迭代到 num = 5。我们使用了一个保护语句,条件表达式是“num % 5 != 0”,这仅仅意味着“num”不能被 5 整除。现在对于 num = 1 到 num = 4,保护语句的主体不会被执行,因为 num 不能被 5 整除。对于 num=5,守卫的主体,在到达守卫语句内部时,首先 num 将加一,但由于我们在它之后有中断控制语句,所以while 循环将在此时停止,程序的控制流从 while 循环中出来。

迅速

// 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
}

输出:

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

1
2
3
4

同样,我们可以通过使用 for 循环来获得相同的结果。

函数中的 Guard 语句

Guard 语句也可以与函数一起使用。但是我们仅在处理函数中的保护语句时使用以下控制语句,

  • return:此时停止函数的执行,程序的控制流从函数中出来。
  • throw:如果出现问题,这会引发错误,并且可以在 catch 块的帮助下捕获异常。

让我们一一详细讨论:

带有返回控制语句的 Guard 语句

带有“return”控制语句的保护语句具有以下形式,

func myFunction (parameters (optional)){

    // statement 1

   guard condition else {

       // body

      return

  }
  //  statement 2
}

// Calling function
myFunction(arguments)

这里,func 是关键字,myFunction 是函数名。

如果保护语句的条件表达式为真,则保护语句的主体不会被执行,程序的控制流将直接进入语句 2,并且一旦条件表达式为真,该语句就会被执行。

否则,如果保护语句的条件表达式计算为假,那么保护语句的主体将被执行,程序的控制流进入保护语句内部,其主体将被执行。由于我们在执行主体的所有语句之后使用了“return”语句,因此这个“return”语句也被执行。由于这个“return”语句,函数执行将在此时停止,因此程序的流控制最终会从函数体中出来。

例子:

在下面的程序中,我们使用保护语句检查传递的整数 num 是否可以被 5 整除。如果条件评估为假,则将执行包含要打印的打印语句“不能被 5 整除”的保护语句的主体。由于我们在 print 语句之后使用了 return 语句,因此程序的控制流目前来自函数体。否则,将跳过守卫的主体,并执行守卫语句结束后的打印语句,将“可被 5 整除”打印到控制台。

迅速

// 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)

输出:

Divisible by 5
Not divisible by 5

带有 throw 控制语句的 Guard 语句

带有“throw”控制语句的保护语句具有以下形式,

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()
}

这里,func 是 Keyword,myFunction 是函数名,error 是抛出的错误。

如果保护语句的条件表达式为真,则保护语句的主体不会被执行,程序的控制流将直接进入语句 2,并且一旦条件表达式为真,该语句就会被执行。

否则,如果保护语句的条件表达式计算为假,那么保护语句的主体将被执行,程序的控制流进入保护语句内部,其主体将被执行。由于我们在执行主体的所有语句之后使用了“抛出”控制语句,因此该语句也被执行。正因为如此,函数的执行会因为抛出错误而停止,因此程序的流控制最终会从函数体中出来。我们可以在 do-catch 块的帮助下轻松处理此错误。

例子:

在下面的程序中,我们试图将字符串转换为等效的整数。首先,我们尝试在 Int() 初始化程序的帮助下将字符串转换为等效的整数。请注意,传递的字符串可以是非数字的,这就是为什么我们也传递了一个可选值 (-1)。现在如果变量“integerValue”的值不等于-1,那么guard语句的主体将不会被执行,程序的流控制将到达打印语句。否则,如果它等于 -1,则意味着传递的字符串是非数字字符串,因此保护语句的条件表达式将评估为 false,并且其主体将被执行,引发错误,这是以下情况之一“stringError”枚举,该函数通过打印消息来处理错误。否则,该函数会将错误传播到其调用站点。现在错误被 catch 捕获了。

迅速

// 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)")
}

输出:

integerValue: 12345
[X] wrong string format: non_numeric_string

守卫有多个条件

Guard 语句可以评估由逗号 (,) 分隔的多个条件。如果至少一个条件评估为假,则将执行保护语句的主体。换句话说,当且仅当所有条件都评估为真,那么在这种情况下,保护语句的主体不会像逻辑 AND 那样被执行。否则,guard 语句的主体将始终被执行。语法如下,

句法:

这里,条件 1、条件 2……是条件表达式

例子:

在下面的程序中,我们对 num 的值施加了两个条件。 num 小于或大于 1 且 num 小于 10。如果这个条件不满足,则执行guard语句的主体,否则,将跳过guard语句的主体,执行guard语句之后的print语句。

迅速

// 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)

输出:

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

Guard-let 声明

我们也可以使用guard let-statement。在下面的程序中,我们初始化了一个变量 str 作为可选类型。在guard-let 语句中,我们正在检查“str”是否包含值。由于 str 包含一个值,因此表达式的计算结果为 true,而 guard-let 语句的主体不会被执行。

例子:

迅速

// 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()

输出:

myString: GeeksforGeeks

guard 和 if 语句的区别

guard 语句和 if 语句的区别在于,对于相同的条件表达式,如果条件表达式的值为 false,则执行“guard”语句的主体,如果条件表达式的值为 true,则执行“if”语句的主体.此外,在guard 语句的情况下,它必须有一个控制语句来更改程序的控制流,但对于if 语句不是强制性的。

例子:

在程序中,我们创建了两个函数来说明两者的区别。在“checkUsingIf”函数中,我们使用了一个 if 语句来检查传递给函数的字符串是否等于“GeeksforGeeks”。如果是这样,那么 if 语句的主体将被执行,程序的控制流一到达 return 语句就会从函数主体中出来。否则,打印语句 print(“GeeksforGeeks and \(myString) are the same.”) 将被执行。

在“checkUsingGuard”函数中,我们使用了一个guard语句来检查传递给函数的字符串是否不等于“GeeksforGeeks”。如果相等,则执行guard语句体,程序的控制流一到return语句就从函数体中出来。否则,打印语句 print(“GeeksforGeeks and \(myString) are different.”) 将被执行。

迅速

// 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")

输出:

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