Un slice es una referencia a una parte contigua de una colección de datos, como un array o un Vec<T>. A diferencia de una colección, un slice no posee los datos; es simplemente una “vista” que permite inspeccionar o manipular un subconjunto de la memoria original sin necesidad de copiar los elementos.
Técnicamente, un slice es un “puntero pesado” (fat pointer). Mientras que un puntero estándar solo contiene la dirección de memoria de un elemento, un slice en Rust es una estructura compuesta por dos valores: un puntero al primer elemento de la secuencia y la longitud (length) de la porción seleccionada. Esto permite que Rust verifique los límites de la memoria en tiempo de ejecución, garantizando la seguridad.
Se utilizan slices principalmente para mejorar la eficiencia (evitando copias innecesarias) y para la abstracción. Por ejemplo, en lugar de escribir una función que acepte solo arrays de tamaño fijo, se utiliza &[T] para que la función pueda aceptar tanto arrays como Vec<T>. Un error común al trabajar con slices es intentar mantener una referencia a un slice después de que la colección original (su dueña) haya salido de ámbito (scope), lo que resultaría en un error de lifetime o puntero colgante.
fn main() {
// 1. Slices sobre un array
let arraya = [10, 20, 30, 40, 50];
let slice_parcial = &arraya[1..4]; // Rango exclusivo: elementos en índices 1, 2, 3
let slice_inicio = &arraya[..2]; // Desde el inicio hasta índice 1
let slice_final = &arraya[3..]; // Desde índice 3 hasta el final
let slice_todo = &arraya[..]; // Referencia a toda la secuencia
// 2. Slices sobre un Vec (funcionan igual que los arrays)
let vec_dinamico = vec![1, 2, 3, 4, 5];
let slice_vec = &vec_dinamico[1..4];
// 3. Slices de strings (&str)
// Las strings en Rust son secuencias UTF-8; &str es un slice de ellas
let cadena = String::from("Hola Rust");
let slice_texto: &str = &cadena[0..4]; // "Hola"
// 4. Métodos y seguridad
println!("Slice parcial: {:?}", slice_parcial);
println!("¿El slice_vec tiene elementos?: {}", slice_vec.is_empty());
// Uso de .get() para evitar pánico (retorna Option)
match slice_parcial.get(10) {
Some(val) => println!("Valor encontrado: {}", val),
None => println!("Índice fuera de rango de forma segura"),
}
// 5. Flexibilidad: funciones que aceptan slices
procesar_datos(slice_parcial);
procesar_datos(slice_vec);
// 6. Mutabilidad (requiere declarar la colección como mut)
let mut arraya_mut = [1, 2, 3, 4, 5];
let slice_mut = &mut arraya_mut[0..3];
slice_mut.reverse(); // Invierte el subconjunto seleccionado
println!("Array mutado: {:?}", arraya_mut);
}
// Esta función acepta cualquier secuencia de i32 (array o Vec) mediante un slice
fn procesar_datos(datos: &[i32]) {
let suma: i32 = datos.iter().sum();
println!("La suma de la secuencia es: {}", suma);
}
Explicación del Código
arraya: Un array estático de tipo[i32; 5]. Se utiliza para demostrar cómo crear diferentes tipos de vistas mediante la sintaxis de rangos.slice_parcial: Un slice de tipo&[i32]que apunta a los elementos20, 30, 40. El rango1..4indica que el límite superior es exclusivo.slice_inicio,slice_finalyslice_todo: Demuestran la versatilidad de la sintaxis de rangos (..) para omitir el inicio o el final de la secuencia.vec_dinamicoyslice_vec: Muestran que unVec<T>puede ser “rebanado” de la misma forma que un array, creando un&[T].cadenayslice_texto:cadenaes unString(poseído), mientras queslice_textoes un&str(un slice de caracteres UTF-8).slice_parcial.get(10): El métodogetdevuelve unOption<&T>. A diferencia del acceso directo con[](que causaría un panic si el índice no existe),getpermite manejar la ausencia de datos de forma segura mediante unmatch.procesar_datos: Esta función es clave para la modularidad. Al aceptardatos: &[i32]en lugar deVec<i32>, permite que el programa sea más genérico y eficiente, aceptando tanto elslice_parcial(del array) como elslice_vec(del vector) sin necesidad de realizar copias de memoria o usar genéricos complejos.slice_mut: Un slice mutable que permite modificar directamente el contenido dearraya_mutmediante métodos comoreverse(), demostrando que los slices pueden ser tanto inmutables como mutables.
N° 17