Arrays en Rust
Un array (arreglo) es una lista de valores de tamaño fijo, todos del mismo tipo. La clave está en “tamaño fijo”: una vez que creas un array, no puede crecer ni encogerse. Si necesitas algo que cambie de tamaño, para eso está el vector.
Crear un array
Sección titulada «Crear un array»fn main() { let numbers: [i32; 5] = [1, 2, 3, 4, 5]; println!("{:?}", numbers);}El tipo [i32; 5] se lee como “un array de 5 valores i32”. Esa longitud forma parte del tipo: [i32; 5] y [i32; 3] se consideran tipos distintos.
También puedes dejar que Rust deduzca el tipo y escribir solo los valores:
let numbers = [1, 2, 3, 4, 5];El mismo valor, repetido
Sección titulada «El mismo valor, repetido»Para llenar un array con el mismo valor N veces, usa este atajo:
fn main() { let zeros = [0; 5]; // [0, 0, 0, 0, 0] println!("{:?}", zeros);}Acceder a los elementos
Sección titulada «Acceder a los elementos»Los arrays se numeran empezando desde 0, y se accede a ellos con corchetes:
fn main() { let fruits = ["manzana", "banana", "cereza"];
println!("{}", fruits[0]); // manzana println!("{}", fruits[2]); // cereza println!("Longitud: {}", fruits.len());}Los accesos fuera de rango se detectan
Sección titulada «Los accesos fuera de rango se detectan»Si intentas acceder a un índice que no existe, Rust detiene tu programa en lugar de leer en silencio memoria basura:
fn get_fruit(fruits: [&str; 3], index: usize) -> &str { fruits[index]}
fn main() { let fruits = ["manzana", "banana", "cereza"]; println!("{}", get_fruit(fruits, 10)); // hace panic en tiempo de ejecución}thread 'main' (12345) panicked at src/main.rs:2:5:index out of bounds: the len is 3 but the index is 10Rust te avisa de que hubo un panic (el programa se detuvo de golpe) en la línea 2, porque el índice 10 está fuera de rango: el array tiene longitud 3.
Recorrer un array con un bucle
Sección titulada «Recorrer un array con un bucle»fn main() { let numbers = [10, 20, 30];
for n in numbers { println!("{n}"); }}Arrays de arrays (arrays 2D)
Sección titulada «Arrays de arrays (arrays 2D)»Un array puede contener otros arrays. Eso te da una cuadrícula con filas y columnas, como un tablero de juego o una hoja de cálculo pequeña. El tipo de grid en el ejemplo es [[i32; 3]; 2], que se lee como “2 filas, cada una un array de 3 valores i32”.
fn main() { // 2 filas, 3 columnas let grid = [ [1, 2, 3], [4, 5, 6], ];
println!("Fila 1, columna 2: {}", grid[1][2]);
let mut total = 0; for row in grid { println!("{:?}", row); for value in row { total += value; } } println!("Total: {total}");}Salida:
Fila 1, columna 2: 6[1, 2, 3][4, 5, 6]Total: 21grid[1][2] significa “la fila 1 y, dentro de ella, la columna 2”. Las dos se cuentan desde 0, así que es la segunda fila, tercer valor. Para visitar todos los valores, usa un bucle para las filas y otro bucle dentro para los valores de cada fila.
Todas las filas tienen que tener la misma longitud, porque la longitud de la fila forma parte del tipo. Si además necesitas la posición mientras recorres, .iter().enumerate() te da el índice y el valor juntos. Lo tienes en la página del bucle for.
Arrays frente a vectores
Sección titulada «Arrays frente a vectores»Usa un array cuando el tamaño es fijo y lo conoces de antemano (como los siete días de la semana). Usa un Vec cuando necesites añadir o quitar elementos, que en la práctica es casi siempre. En el código Rust del día a día, los arrays son menos comunes que los vectores.
Práctica
Sección titulada «Práctica»1. Suma y media
Sección titulada «1. Suma y media»Crea el array [4, 8, 15, 16, 23, 42]. Suma todos los valores e imprime la suma y la media con dos decimales. Pista: recórrelo con for, lleva un total acumulado y convierte los dos números a f64 con as antes de dividir.
Ver solución
fn main() { let numbers = [4, 8, 15, 16, 23, 42];
let mut total = 0; for n in numbers { total += n; }
let average = total as f64 / numbers.len() as f64; println!("Suma: {total}"); println!("Media: {average:.2}");}Salida:
Suma: 108Media: 18.00Sin as f64, total / numbers.len() sería una división entera, y además Rust se quejaría de que total (un i32) y len() (un usize) son de tipos distintos.
2. El día más caluroso
Sección titulada «2. El día más caluroso»Tienes las temperaturas de una semana: [18, 25, 12, 31, 22, 27, 19]. Encuentra e imprime la más alta. Pista: empieza con let mut hottest = temps[0]; y luego recorre el array y reemplázala cada vez que encuentres un valor mayor.
Ver solución
fn main() { let temps = [18, 25, 12, 31, 22, 27, 19];
let mut hottest = temps[0]; for t in temps { if t > hottest { hottest = t; } }
println!("Día más caluroso: {hottest}");}Salida:
Día más caluroso: 31Empezar desde temps[0] en lugar de 0 importa: si todas las temperaturas estuvieran bajo cero, empezar en 0 daría una respuesta equivocada.
Resumen
Sección titulada «Resumen»- Los arrays tienen una longitud fija que forma parte de su tipo:
[i32; 5]. - Accede a los elementos con
array[índice], empezando desde 0. - Un acceso fuera de rango provoca un panic en tiempo de ejecución, en lugar de un comportamiento indefinido.
- Los arrays pueden contener arrays:
[[i32; 3]; 2]es una cuadrícula que lees congrid[fila][columna]. - Si necesitas cambiar el tamaño, usa un
Vec.
Comprueba lo que aprendiste
Sección titulada «Comprueba lo que aprendiste»Comprueba lo aprendido
1. ¿Qué es cierto sobre la longitud de un array en Rust?
2. ¿Qué pasa si, en tiempo de ejecución, accedes a un índice de un array que está fuera de rango?
3. ¿Qué crea let zeros = [0; 5];?
Puntuación: 0 / 3
Para leer más
Sección titulada «Para leer más»- El tipo array — El libro de Rust (en inglés): la introducción oficial a los arrays, incluido por qué la longitud forma parte del tipo.
- Arrays y slices — Rust by Example (en inglés): ejemplos cortos y ejecutables, y un primer vistazo a los slices.
- Recorrer una colección con
for— El libro de Rust (en inglés): por qué un buclefores más seguro que recorrer un array con un índice. array— documentación de la biblioteca estándar (en inglés): lo que pueden hacer los arrays, comomapyas_slice, y cómo también aprovechan todos los métodos de los slices.