Rebanadas de Vec<T> en Rust: ¿cómo funcionan y para qué sirven?
\n\nSi alguna vez has programado en Rust y te has preguntado "How do I get a slice of a Vec<T> in Rust?" — no estás solo. Es una de las preguntas más populares en Stack Overflow, con miles de visitas. Y con razón: trabajar con vectores y sus slices es una habilidad fundamental, sin la cual no se puede imaginar ningún proyecto serio en Rust.
\n\nEn este artículo no solo mostraremos cómo obtener un slice. Analizaremos las mejores prácticas de 2025, aprenderemos a evitar errores típicos y entenderemos por qué Rust nos obliga a pensar tanto en los préstamos. ¡Allá vamos!
\n\n¿Qué es un slice en Rust?
\n\nAntes de obtener un slice, entendamos qué es. Un slice es una referencia a una secuencia contigua de elementos en memoria. En Rust, un slice se denota como &[T]. No es una estructura de datos propietaria — solo «observa» una parte de los datos que pertenecen a otro (por ejemplo, un vector o un array).
La principal ventaja de los slices es la seguridad. El compilador de Rust garantiza que no saldrás de los límites de la memoria, y el sistema de préstamos no te permitirá modificar los datos mientras haya referencias activas a ellos.
\n\n¿Por qué no usar el vector directamente?
\n\nUn vector (Vec<T>) es una estructura propietaria. Si lo pasas a una función, o lo mueves (perdiendo el acceso) o pasas una referencia. Los slices te dan flexibilidad: puedes pasar solo una parte de los datos, sin copiarlos ni perder el control sobre el vector original.
Por ejemplo, trabajas con un gran conjunto de datos y quieres pasar un fragmento a una función para su análisis. El slice es la herramienta ideal: es ligero (solo dos palabras: puntero y longitud) y seguro.
\n\nFormas principales de obtener un slice de Vec<T>
\n\nPasemos a la práctica. Hay varias formas de obtener un slice de un vector. Veremos las más populares y convenientes.
\n\n1. Operador de indexación: &vec[start..end]
\n\nLa forma más directa es usar el operador de rango ..:
let vec = vec![1, 2, 3, 4, 5];\nlet slice: &[i32] = &vec[1..4]; // slice del índice 1 al 4 (sin incluir el 4)\nprintln!("{:?}", slice); // [2, 3, 4]\n\nEste método utiliza una verificación de límites en tiempo de ejecución. Si te sales de los límites del vector, el programa entrará en pánico (panic). Para ejemplos de aprendizaje está bien, pero en código de producción hay que tener cuidado.
\n\nPuedes usar varias formas de rangos:
\n\n- \n
&vec[..]— todo el vector \n&vec[2..]— desde el índice 2 hasta el final \n&vec[..3]— desde el inicio hasta el índice 3 (sin incluirlo) \n&vec[1..=3]— desde 1 hasta 3 inclusive \n
2. Método .as_slice()
\n\nEste método devuelve un slice de todo el vector. Es más seguro que &vec[..] porque expresa explícitamente la intención:
let vec = vec![10, 20, 30];\nlet slice: &[i32] = vec.as_slice();\nprintln!("{:?}", slice); // [10, 20, 30]\n\nEl método as_slice() es especialmente útil cuando quieres enfatizar que estás trabajando con un slice, no con un vector. Esto hace que el código sea más legible y autodocumentado.
3. Obtener un slice mutable: as_mut_slice()
\n\nSi necesitas modificar los elementos dentro del slice (pero no el vector en sí), usa as_mut_slice():
let mut vec = vec![1, 2, 3];\nlet slice: &mut [i32] = vec.as_mut_slice();\nslice[0] = 100;\nprintln!("{:?}", vec); // [100, 2, 3]\n\nTen en cuenta: el vector debe declararse como mut. Tampoco puedes tener simultáneamente un slice inmutable y uno mutable — esto violaría las reglas de préstamo.