Ejercicio: Uso de un bucle para iterar por datos
En este ejercicio, modificará el programa de fábrica de automóviles para usar un bucle a fin de iterar por los pedidos de automóviles.
Se actualizará la función main
para agregar una expresión de bucle a fin de procesar el conjunto completo de pedidos. La estructura de bucle permite reducir la redundancia en el código. Al simplificar el código, se puede aumentar fácilmente la cantidad de pedidos.
En la función car_factory
, se agregará otro bucle para evitar el estado de alarma en tiempo de ejecución en un valor fuera de los límites.
El desafío consiste en finalizar el código de ejemplo para que se compile y se ejecute.
Para trabajar en el código de ejemplo de este ejercicio, tiene dos opciones:
- Copiar el código y editarlo en el entorno de desarrollo local.
- Abrir el código en un Área de juegos de Rust preparada.
Nota
En el código de ejemplo, busque la macro todo!
. Esta macro indica el código que debe completarse o actualizarse.
Carga del programa
Si ha cerrado el código del programa del último ejercicio, puede volver a abrirlo en esta Área de juegos de Rust preparada.
Asegúrese de recompilar el programa y de que todavía se ejecuta sin errores del compilador.
Repetición de acciones con una expresión de bucle
Es necesario actualizar el programa para admitir más pedidos. La estructura de código actual usa instrucciones redundantes para admitir seis pedidos. La redundancia es complicada y difícil de mantener.
Se puede simplificar la estructura mediante una expresión de bucle para repetir las acciones a fin de crear cada pedido. Con el código simplificado, se puede crear rápidamente un gran número de pedidos.
En la función
main
, quite las instrucciones siguientes. Este bloque de código define y establece la variableorder
, llama a la funcióncar_factory
y a la macroprintln!
para los pedidos de automóviles, e inserta cada pedido en el mapa hashorders
.Rust// Order 6 cars // - Increment "order" after each request // - Add each order <K, V> pair to "orders" hash map // - Call println! to show order details from the hash map // Initialize order variable let mut order = 1; // Car order #1: Used, Hard top car = car_factory(order, 1000); orders.insert(order, car); println!("Car order {}: {:?}", order, orders.get(&order)); ... // Car order #6: Used, Hard top order = order + 1; car = car_factory(order, 4000); orders.insert(order, car); println!("Car order {}: {:?}", order, orders.get(&order));
Reemplace las instrucciones quitadas por el bloque de código siguiente:
Rust// Start with zero miles let mut miles = 0; todo!("Add a loop expression to fulfill orders for 6 cars, initialize `order` variable to 1") { // Call car_factory to fulfill order // Add order <K, V> pair to "orders" hash map // Call println! to show order details from the hash map car = car_factory(order, miles); orders.insert(order, car); println!("Car order {}: {:?}", order, orders.get(&order)); // Reset miles for order variety if miles == 2100 { miles = 0; } else { miles = miles + 700; } }
Agregue una expresión de bucle que repita las acciones a fin de crear pedidos para seis automóviles. Necesitará una variable
order
inicializada en 1.Compile el programa. Asegúrese de que el código se compila sin errores.
Debería mostrarse una salida similar a esta de ejemplo:
Car order 1: Some(Car { color: "Blue", motor: Manual, roof: true, age: ("New", 0) })
Car order 2: Some(Car { color: "Green", motor: SemiAuto, roof: false, age: ("Used", 700) })
Car order 3: Some(Car { color: "Red", motor: Automatic, roof: true, age: ("Used", 1400) })
Car order 4: Some(Car { color: "Silver", motor: SemiAuto, roof: false, age: ("Used", 2100) })
Car order 5: Some(Car { color: "Blue", motor: Manual, roof: true, age: ("New", 0) })
Car order 6: Some(Car { color: "Green", motor: Automatic, roof: true, age: ("Used", 700) })
Aumento de pedidos de automóviles a 11
Ahora en el programa se usa un bucle para cumplimentar los pedidos de seis automóviles. ¿Qué ocurre si se piden más de seis automóviles?
Actualice la expresión de bucle en la función
main
para pedir 11 automóviles:Rusttodo!("Update the loop expression to create 11 cars");
Recompile el programa. En tiempo de ejecución, el programa entra en estado de alarma.
OutputCompiling playground v0.0.1 (/playground) Finished dev [unoptimized + debuginfo] target(s) in 1.26s Running `target/debug/playground` thread 'main' panicked at 'index out of bounds: the len is 4 but the index is 4', src/main.rs:34:29
Ahora se verá cómo resolver este problema.
Prevención del estado de alarma en tiempo de ejecución con una expresión de bucle
En la función car_factory
, se usa una expresión if/else a fin de comprobar el valor del índice color
para la matriz colors
:
// Prevent panic: Check color index for colors array, reset as needed
// Valid color = 1, 2, 3, or 4
// If color > 4, reduce color to valid index
let mut color = order as usize;
if color > 4 {
// color = 5 --> index 1, 6 --> 2, 7 --> 3, 8 --> 4
color = color - 4;
}
La matriz colors
tiene cuatro elementos y el intervalo del índice color
válido es de 0 a 3. La expresión condicional comprueba si el índice color
es mayor que 4. (No se comprueba si el índice color
es igual a 4. Más adelante en la función, cuando indexamos en la matriz para asignar el color del automóvil, restamos uno del valor del índice: color - 1
. Un valor color
de 4 se procesa como colors[3]
en la matriz).
La expresión if/else actual funciona bien para evitar que el tiempo de ejecución entre en estado de alarma cuando se piden ocho automóviles o menos. Pero si se piden 11 automóviles, el programa entra en estado de alarma en el noveno pedido. Es necesario ajustar la expresión para que sea más sólida. Para realizar esta mejora, se usará otra expresión de bucle.
En la función
car_factory
, reemplace la instrucción condicional if/else por una expresión de bucle. Revise las instrucciones de pseudocódigo siguientes para evitar un estado de alarma en tiempo de ejecución si el valor del índicecolor
es mayor que 4.Rust// Prevent panic: Check color index, reset as needed // If color = 1, 2, 3, or 4 - no change needed // If color > 4, reduce to color to a valid index let mut color = order as usize; todo!("Replace `if/else` condition with a loop to prevent run-time panic for color > 4");
Sugerencia
En este caso, el cambio de una condición if/else a una expresión de bucle es muy sencilla.
Compile el programa. Asegúrese de que el código se compila sin errores.
Debería ver la siguiente salida:
Car order 1: Some(Car { color: "Blue", motor: Manual, roof: true, age: ("New", 0) })
Car order 2: Some(Car { color: "Green", motor: SemiAuto, roof: false, age: ("Used", 700) })
Car order 3: Some(Car { color: "Red", motor: Automatic, roof: true, age: ("Used", 1400) })
Car order 4: Some(Car { color: "Silver", motor: SemiAuto, roof: false, age: ("Used", 2100) })
Car order 5: Some(Car { color: "Blue", motor: Manual, roof: true, age: ("New", 0) })
Car order 6: Some(Car { color: "Green", motor: Automatic, roof: true, age: ("Used", 700) })
Car order 7: Some(Car { color: "Red", motor: Manual, roof: true, age: ("Used", 1400) })
Car order 8: Some(Car { color: "Silver", motor: SemiAuto, roof: false, age: ("Used", 2100) })
Car order 9: Some(Car { color: "Blue", motor: Automatic, roof: true, age: ("New", 0) })
Car order 10: Some(Car { color: "Green", motor: SemiAuto, roof: false, age: ("Used", 700) })
Car order 11: Some(Car { color: "Red", motor: Manual, roof: true, age: ("Used", 1400) })
Solución
Puede comparar la salida del programa con la solución de este ejercicio en esta Área de juegos de Rust.