Ir al contenido

Vectores en Rust

Un vector (Vec) es como un array, pero puede crecer y encogerse mientras el programa se ejecuta. En el código Rust del día a día, cuando necesitas una lista de cosas, vas a usar un Vec mucho más a menudo que un array de tamaño fijo.

fn main() {
let numbers: Vec<i32> = vec![1, 2, 3];
println!("{:?}", numbers);
}

vec![] es una macro (fíjate en el !) que construye un Vec a partir de una lista de valores, de forma parecida a como escribirías un array.

▶ Pruébalo tú mismo

También puedes empezar con uno vacío e ir llenándolo:

let mut numbers: Vec<i32> = Vec::new();

Usa .push() para añadir al final. El vector tiene que ser mut, porque lo estás modificando:

fn main() {
let mut numbers = Vec::new();
numbers.push(1);
numbers.push(2);
numbers.push(3);
println!("{:?}", numbers);
}

Salida:

[1, 2, 3]
▶ Pruébalo tú mismo

Con la misma sintaxis de corchetes que los arrays:

fn main() {
let fruits = vec!["manzana", "banana", "cereza"];
println!("{}", fruits[0]);
println!("Longitud: {}", fruits.len());
}
▶ Pruébalo tú mismo

Si quieres una búsqueda más segura, que no haga panic con un índice incorrecto, usa .get(), que te devuelve un Option (lo verás con calma en la página de Option):

fn main() {
let fruits = vec!["manzana", "banana", "cereza"];
match fruits.get(10) {
Some(fruit) => println!("Encontrada: {fruit}"),
None => println!("No hay ninguna fruta en ese índice"),
}
}
▶ Pruébalo tú mismo
fn main() {
let mut numbers = vec![1, 2, 3, 4, 5];
numbers.pop(); // quita el último elemento -> [1, 2, 3, 4]
numbers.remove(0); // quita por índice -> [2, 3, 4]
println!("{:?}", numbers);
}
▶ Pruébalo tú mismo
fn main() {
let numbers = vec![10, 20, 30];
for n in &numbers {
println!("{n}");
}
}
▶ Pruébalo tú mismo

Fíjate en el & delante de numbers. Recorrer con for n in &numbers toma prestado (borrowing) cada elemento, en lugar de quedarse con el ownership del vector. Si quitas el &, el vector se mueve al bucle y ya no podrás usar numbers después. Casi siempre lo que quieres es tomarlo prestado.

Habrás notado que el tipo se escribe Vec<i32>. La parte <i32> dice “un vector de valores i32”. Esta notación con corchetes angulares se llama genérico, y la verás a fondo en la página de Genéricos. Por ahora, lee Vec<T> como “un vector que guarda valores de tipo T”.

Empieza con un vector vacío. Recorre los números del 1 al 10 y añade solo los pares. Después, imprime el vector y cuántos elementos tiene. Pista: un número n es par cuando n % 2 == 0.

Ver solución
fn main() {
let mut evens = Vec::new();
for n in 1..=10 {
if n % 2 == 0 {
evens.push(n);
}
}
println!("{:?}", evens);
println!("Encontré {} números pares", evens.len());
}

Salida:

[2, 4, 6, 8, 10]
Encontré 5 números pares
▶ Pruébalo tú mismo

Fíjate en que nunca escribimos el tipo. Rust ve las llamadas a push(n) y deduce que evens es un Vec<i32>.

Pon tres platos en un vector: "azul", "verde" y luego "rojo". Saca dos platos de arriba con .pop() e imprime cada uno. Por último, imprime lo que queda. Pista: .pop() devuelve un Option, así que imprímelo con {:?}.

Ver solución
fn main() {
let mut plates = Vec::new();
plates.push("azul");
plates.push("verde");
plates.push("rojo");
println!("Saqué {:?}", plates.pop());
println!("Saqué {:?}", plates.pop());
println!("Quedan: {:?}", plates);
}

Salida:

Saqué Some("rojo")
Saqué Some("verde")
Quedan: ["azul"]
▶ Pruébalo tú mismo

pop() siempre saca el último elemento que añadiste, como quien toma el plato de arriba de una pila. Devuelve Some(...) y no el valor a secas, porque el vector podría estar vacío. En ese caso obtendrías None en lugar de un fallo.

  • Vec<T> es una lista que puede crecer; créala con vec![...] o Vec::new().
  • .push() añade al final; .pop() quita el último elemento; .remove(i) quita por índice.
  • vec[i] hace panic con un índice incorrecto; .get(i) devuelve un Option y no hace panic.
  • Recorre con for item in &vec para tomar prestados los elementos en lugar de consumir el vector.

Comprueba lo aprendido

1. ¿Qué pasa si accedes a un Vec con un índice incorrecto, como numbers[10]?

2. ¿Qué método te permite consultar un índice sin arriesgarte a un panic?

3. ¿Qué hace el & en for n in &numbers?

Puntuación: 0 / 3