Swift proporciona un tipo especial de declaración denominada declaración de «guardia». Una declaración de guardia es capaz de transferir el flujo de control de un programa si no se cumplen ciertas condiciones dentro del programa. O podemos decir, si una expresión de condición se evalúa como verdadera, entonces el cuerpo de la declaración de guardia no se ejecuta. En otras palabras, el flujo de control del programa no va dentro del cuerpo de la declaración de guardia. De lo contrario, si la condición se evalúa como falsa, se ejecuta el cuerpo de la declaración de guardia.
Sintaxis:
condición de guardia más {
// cuerpo
}
El valor de cualquier condición debe ser de tipo booleano. La condición puede ser una declaración vinculante opcional. Cuando se asigna un valor a una variable desde una declaración de vinculación opcional en una instrucción de protección, la condición se puede usar para el resto del ámbito de inclusión de la instrucción de protección.
La cláusula else de una declaración de guardia es necesaria y debe llamar a una función sin tipo de retorno o transferir el control del programa fuera del alcance de la declaración de guardia usando una de las siguientes declaraciones:
- descanso
- devolver
- Seguir
- lanzar
Declaración de guardia en un bucle
Las declaraciones de guardia se pueden usar dentro de un bucle. Pero usamos las declaraciones de control a continuación solo cuando tratamos con una declaración de guardia en un bucle,
- continuar: Salta la iteración actual en ese momento y pasa a la siguiente iteración si existe.
- break: detiene la iteración por completo y el flujo de control sale del cuerpo del bucle.
Discutámoslos uno por uno en detalle:
Declaración de guardia con declaración de control continuo:
Una declaración de guardia con una declaración de control «continuar» tiene la siguiente forma,
loop { // statement 1 guard condition else { // body continue } // statement 2 }
Aquí, el bucle es uno de los bucles, es decir, for, while
Si la expresión de condición de la declaración de guardia se evalúa como verdadera, entonces el cuerpo de la declaración de guardia no se ejecuta y el flujo de control del programa vendría directamente a la declaración 2 y esta declaración se ejecutaría tan pronto como la expresión de condición se evalúe como verdadera.
De lo contrario, si la expresión de condición de la declaración de guardia se evalúa como falsa, el cuerpo de la declaración de guardia se ejecuta y el flujo de control del programa va dentro de la declaración de guardia y su cuerpo se ejecutará. Dado que hemos utilizado la declaración «continuar» justo después de ejecutar todas las declaraciones del cuerpo, esta declaración «continuar» también se ejecuta. Debido a esta declaración de «continuación», la iteración actual se omitiría en ese momento debido a que la declaración 2 no se ejecutaría y el control de flujo del programa pasaría a la siguiente iteración, si existe.
Ejemplo:
En el siguiente programa, estamos iterando desde num = 1 hasta num = 10 usando un bucle while. Estamos usando una declaración de guardia mientras que la expresión de la condición es «num % 5 == 0», lo que simplemente significa que ese número es divisible por 5. Ahora, para num = 1, el cuerpo de la declaración de guardia se ejecutaría como num no es divisible por 5. Al llegar al interior de la declaración de guardia, en primer lugar, num se incrementaría en uno (ahora num se ha convertido en 2), pero dado que tenemos la declaración de control «continuar» justo después, la iteración actual del ciclo while se omitiría en el momento y se ejecutaría la siguiente iteración. Este proceso se repetirá excepto cuando el valor de num llegue a 5 y 10.
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 }
Producción:
Natural numbers from 1 to 10 which are divisible by 5 are: 5 10
Declaración de guardia con declaración de control de interrupción:
Una declaración de guardia con una declaración de control de «ruptura» tiene la siguiente forma,
loop { // statement 1 guard condition else { // body break } // statement 2 }
Aquí, el bucle es uno de los bucles, es decir, for, while.
Si la expresión de condición de la declaración de guardia se evalúa como verdadera, entonces el cuerpo de la declaración de guardia no se ejecuta y el flujo de control del programa vendría directamente a la declaración 2 y esta declaración se ejecutaría tan pronto como la expresión de condición se evalúe como verdadera.
De lo contrario, si la expresión de condición de la declaración de guardia se evalúa como falsa, el cuerpo de la declaración de guardia se ejecuta y el flujo de control del programa va dentro de la declaración de guardia y su cuerpo se ejecutará. Dado que hemos utilizado la declaración de «romper» justo después de ejecutar todas las declaraciones del cuerpo, esta declaración de «romper» también se ejecuta. Debido a esta declaración de «interrupción», la iteración se detendría en el momento debido a que el control de flujo del programa eventualmente aterrizaría en la declaración 2 y, por lo tanto, se ejecutará.
Ejemplo:
En el siguiente programa, estamos iterando de num = 1 a num = 5 usando un bucle while. Estamos usando una declaración de guardia y la expresión de la condición es “num % 5 != 0”, lo que simplemente significa que ese “num” no es divisible por 5. Ahora, para num = 1 a num = 4, el cuerpo de la declaración de guardia no se ejecuta porque num no es divisible por 5. Para num= 5 el cuerpo de la guardia, al llegar dentro de la declaración de guardia, primero num se incrementaría en uno, pero como tenemos la declaración de control de ruptura justo después, entonces el while loop se detendría en este momento y el flujo de control del programa sale del ciclo while.
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 }
Producción:
Natural numbers from 1 to 5 which are not divisible by 5 are: 1 2 3 4
Del mismo modo, podemos lograr los mismos resultados usando un bucle for.
Declaración de guardia en una función
Las declaraciones de guardia también se pueden usar con una función. Pero usamos las declaraciones de control a continuación solo cuando tratamos con una declaración de guardia en una función,
- return: Esto detiene la ejecución de la función en el momento y el flujo de control del programa sale de la función.
- throw: esto arroja un error si algo sale mal y la excepción se puede capturar con la ayuda de un bloque catch.
Discutámoslos uno por uno en detalle:
Declaración de guardia con una declaración de control de retorno
Una declaración de guardia con una declaración de control de «retorno» tiene la siguiente forma,
func myFunction (parameters (optional)){ // statement 1 guard condition else { // body return } // statement 2 } // Calling function myFunction(arguments)
Aquí, func es una palabra clave y myFunction es el nombre de la función.
Si la expresión de condición de la declaración de guardia se evalúa como verdadera, entonces el cuerpo de la declaración de guardia no se ejecuta y el flujo de control del programa vendría directamente a la declaración 2 y esta declaración se ejecutaría tan pronto como la expresión de condición se evalúe como verdadera.
De lo contrario, si la expresión de condición de la declaración de guardia se evalúa como falsa, el cuerpo de la declaración de guardia se ejecuta y el flujo de control del programa va dentro de la declaración de guardia y su cuerpo se ejecutará. Dado que hemos utilizado la declaración de «retorno» justo después de ejecutar todas las declaraciones del cuerpo, esta declaración de «retorno» también se ejecuta. Debido a esta declaración de «retorno», la ejecución de la función se detendría en el momento en que el control de flujo del programa eventualmente saldría del cuerpo de la función.
Ejemplo:
En el siguiente programa, estamos comprobando si el entero pasado, num, es divisible por 5 usando una declaración de guardia. Si la condición se evalúa como falsa, se ejecutará el cuerpo de la declaración de guardia que contiene una declaración de impresión para imprimir, «No divisible por 5». el flujo de control del programa sale del cuerpo de la función en este momento, ya que hemos usado la declaración de retorno justo después de la declaración de impresión. De lo contrario, se omitiría el cuerpo de la guardia y se ejecutaría la declaración de impresión después del final de la declaración de guardia que imprime, «Divisible por 5» en la consola.
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)
Producción:
Divisible by 5 Not divisible by 5
Declaración de guardia con una declaración de control de tiro
Una declaración de guardia con una declaración de control de «lanzamiento» tiene la siguiente forma,
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() }
Aquí, func es una palabra clave, myFunction es el nombre de la función, error es el error generado.
Si la expresión de condición de la declaración de guardia se evalúa como verdadera, entonces el cuerpo de la declaración de guardia no se ejecuta y el flujo de control del programa vendría directamente a la declaración 2 y esta declaración se ejecutaría tan pronto como la expresión de condición se evalúe como verdadera.
De lo contrario, si la expresión de condición de la declaración de guardia se evalúa como falsa, el cuerpo de la declaración de guardia se ejecuta y el flujo de control del programa va dentro de la declaración de guardia y su cuerpo se ejecutará. Dado que hemos utilizado una declaración de control de «lanzamiento» justo después de ejecutar todas las declaraciones del cuerpo, esta declaración también se ejecuta. Debido a esto, la ejecución de la función se detendría en ese momento arrojando un error, por lo que el control de flujo del programa eventualmente saldría del cuerpo de la función. Podemos manejar este error fácilmente con la ayuda de un bloque do-catch.
Ejemplo:
En el siguiente programa estamos tratando de convertir la string en su equivalente entero. En primer lugar, hemos intentado convertir la string a su equivalente entero con la ayuda del inicializador Int(). Tenga en cuenta que la string pasada puede no ser numérica, por eso también hemos pasado un valor opcional (-1). Ahora bien, si el valor de la variable «valorInteger» no es igual a -1, entonces el cuerpo de la declaración de guardia no se ejecutará y el control de flujo del programa llegará a la declaración de impresión. De lo contrario, si es igual a -1, significa que la string pasada es una string no numérica y, por lo tanto, la expresión de condición de la declaración de guardia se evaluará como falsa y se ejecutará su cuerpo que arroja un error que es uno de los casos de la enumeración «stringError», la función maneja el error imprimiendo un mensaje. De lo contrario, la función propaga el error a su sitio de llamada. Ahora el error es capturado por el retén.
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)") }
Producción:
integerValue: 12345 [X] wrong string format: non_numeric_string
Guardia que tiene múltiples condiciones
Las declaraciones de guardia pueden evaluar múltiples condiciones separadas por comas (,). El cuerpo de la declaración de guardia se ejecutará si al menos una condición se evalúa como falsa. En otras palabras, si y solo si todas las condiciones se evalúan como verdaderas, entonces en ese caso el cuerpo de la declaración de guardia no se ejecuta como un AND lógico. De lo contrario, el cuerpo de la declaración de guardia siempre se ejecutará. La sintaxis se da a continuación,
Sintaxis:
guard condition1, condition2, ….. else {
// cuerpo
}
Aquí, condición 1, condición 2… son expresiones de condición
Ejemplo:
En el siguiente programa, hemos impuesto dos condiciones para el valor de num. num es menor o mayor que uno y num es menor que diez. Si no se cumple esta condición, se ejecutará el cuerpo de la declaración de guardia; de lo contrario, se omitirá el cuerpo de la declaración de guardia y se ejecutará la declaración de impresión después de la declaración de guardia.
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)
Producción:
4 is less than 10 20 is greater than or equal to 10
Declaración de guardia
También podemos usar la instrucción let-guard. En el siguiente programa hemos inicializado una variable, str como un tipo opcional. En la instrucción guard-let, estamos comprobando si «str» contiene un valor. Como str contiene un valor, la expresión se evalúa como verdadera y el cuerpo de la instrucción guard-let no se ejecuta.
Ejemplo:
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()
Producción:
myString: GeeksforGeeks
Diferencia entre guardia y declaración if
La diferencia entre una declaración de guardia y una declaración if es que para la misma expresión de condición, el cuerpo de la declaración de «guardia» se ejecuta si la expresión de condición se evalúa como falsa y el cuerpo de una declaración «si» se ejecuta si la expresión de condición se evalúa como verdadera. . Además, en el caso de una sentencia de guardia, debe tener una sentencia de control para cambiar el flujo de control del programa, pero no es obligatorio para una sentencia if.
Ejemplo:
En el programa, hemos creado dos funciones para ilustrar la diferencia entre las dos. En la función «checkUsingIf», hemos usado una declaración if para verificar si la string pasada a la función es igual a «GeeksforGeeks». Si es así, entonces se ejecutará el cuerpo de la sentencia if y el flujo de control del programa saldrá del cuerpo de la función tan pronto como llegue a la sentencia return. De lo contrario, se ejecutará la declaración de impresión, print(“GeeksforGeeks y \(myString) son lo mismo.”).
En la función «checkUsingGuard», hemos utilizado una declaración de guardia para verificar si la string pasada a la función no es igual a «GeeksforGeeks». Si es igual, entonces se ejecutará el cuerpo de la sentencia guard y el flujo de control del programa saldrá del cuerpo de la función tan pronto como llegue a la sentencia return. De lo contrario, se ejecutará la declaración de impresión, print(“GeeksforGeeks y \(myString) are different.”).
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")
Producción:
GeeksforGeeks and GeeksforGeeks are the same. GeeksforGeeks and Bhuwanesh Nainwal are different. GeeksforGeeks and GeeksforGeeks are the same. GeeksforGeeks and Bhuwanesh Nainwal are different.