Repeticiones o bucles
- Rust tiene tres tipos de bucles;
loop,whileyfor breakpara interrumpir un buclecontinuepara saltar a la siguiente iteraciónreturnpara salir de funciones, también se puede hacer desde dentro de un loop
loop
- Bucle infinito o hasta detenerlo explícitamente
- Similar a un bucle
while(true) - Para salir del bucle se utiliza
break
loop {
println!("Loop");
break;
}
Retornando valores
- Pueden devolver un valor, el valor se anota después del
break - Uno de los usos de
loopes volver a intentar una operación que se sabe que podría fallar, como verificar si un subproceso ha completado su trabajo o al pedir información al usuario y este ingresa datos no válidos, como letras en lugar de números
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
// Cuando se cumple, termina el bucle
if counter == 10 {
break counter * 2; // Retornando un valor
}
};
println!("The result is {result}"); // 20
}
Loop anidado y etiquetado
- Se etiquetan los loops anidados para evitar confusiones
- Las etiquetas se usan en el
breakocontinuepara especificar a qué bucle se debe aplicar y no al más interno - Las etiquetas deben comenzar con una comilla simple, ejemplo:
'bucle_externo breakycontinuesin etiquetas se aplica al bucle más interno en ese punto
fn main() {
let mut contador_externo = 0;
// Bucle externo etiquetado como 'bucle_externo
'bucle_externo: loop {
println!("Contador del bucle externo: {contador_externo}");
let mut contador_interno = 10;
// Bucle interno
loop {
println!("Cuenta regresiva del bucle interno: {contador_interno}");
// Salir del bucle interno cuando el contador llega a 9
if contador_interno == 9 {
println!("Saliendo del bucle interno");
break;
}
// Salir de ambos bucles cuando el contador externo es 2
if contador_externo == 2 {
println!("Contador externo llegó a 2, saliendo de ambos bucles");
break 'bucle_externo; // <======================== etiquetado
}
contador_interno -= 1;
}
// Incrementar el contador del bucle externo
// después de cada iteración completa del bucle interno
contador_externo += 1;
println!("Completada una iteración del bucle externo\n");
}
// Imprimir el valor final del contador externo
println!("Contador externo final: {contador_externo}");
}
while bucles condicionales
- El código se ejecuta repetidamente mientras la condición sea
true - Cuando deja de ser
trueel programa o código llama automáticamente abreak - Es posible implementar manualmente este comportamiento utilizando
loop,if,elseybreak
fn main() {
let mut number = 5;
while number != 0 {
println!("{}!", number);
number -= 1;
}
println!("End.");
}
- También se puede utilizar
whilepara recorrer una colección, como una matriz (array) - Este enfoque es propenso a errores porque se puede intentar acceder a un índice no válido
- También es lento, porque el compilador agrega código de tiempo de ejecución para realizar la verificación condicional de si el índice está dentro de los límites de la matriz en cada iteración a través del bucle.
- Como alternativa utilizar el bucle
for
fn main() {
let a = [10, 20, 30, 40, 50];
let mut index = 0;
while index < 5 {
println!("the value is: {}", a[index]);
index += 1;
}
}
for recorriendo colecciones
- Se utiliza para recorrer una colección de elementos, como un array
- Se puede utilizar con rangos
- Se puede utilizar como iterador
Como iterador
- Es más seguro que utilizar
whileporque se elimina la posibilidad de errores que podrían resultar de ir más allá del final de la matriz o de no ir lo suficientemente lejos y perder algunos elementos
fn main() {
let letras = ['a', 'b', 'c', 'd', 'e'];
for element in letras {
println!("Letra: {element}");
}
}
Con rangos
- Para ejecutar el código cierta cantidad de veces, como una cuenta regresiva
- La forma de hacerlo es con un
Rangede la biblioteca estándar que genera todos los números en secuencia, comenzando desde un número y terminando antes de otro - (En el ejemplo,
revse utiliza para invertir el rango)
fn main() {
for number in (1..5).rev() {
println!("{}!", number); // 4, 3, 2 y 1
}
}