Arreglos y slices
Un arreglo es una colección de objetos del mismo tipo t, almacenado en memoria contigua. Los arreglos se crean usando corchetes cuardrados [], y su longitud, que se conoce en el momento de la compilación, es parte de su anotación de tipo [T; longitud].
Las slices son similares a los arreglos, pero su longitud no se conoce al momento de compilar.En cambio, un slice es un objeto de dos ‘words’ del procesador; la primera palabra es un puntero a losdatos, la segunda palabra es la longitud del slice. El tamaño de la palabra es el mismoque usize, el cual se determina por la arquitectura del procesador, e.g. 64 bits en x86-64. Los slices se pueden usar para tomar un borrow de una sección de un arreglo y tener la anotaciónde tipo &[t].
use std::mem;
// Esta funcion hace borrow a una slice.
fn analyze_slice(slice: &[i32]) {
println!(" El primer elemento de un slice: {}", slice[0]);
println!("El slice tiene {} elementos", slice.len());
}
fn main() {
// Arreglos de tamaño fijo (su anotación de tipo es superflua).
let xs: [i32; 5] = [1, 2, 3, 4, 5];
// Todos los elementos pueden ser inicializados al mismo valor.
let ys: [i32; 500] = [0; 500];
// Los índices empiezan en 0.
println!("El primer elemento del arreglo: {}", xs[0]);
println!("El segundo elemento del arreglo: {}", xs[1]);
// `len` regresa cuántos elementos hay en el arreglo.
println!("Número de elementos en el arreglo: {} ", xs.len());
// Los arreglos se colocan en el stack.
println!("Los arreglos ocupan {} bytes", mem::size_of_val(&xs));
// Los arreglos pueden ser `borrowed` como slices.
println!("Hace borrow de todo el arreglo como un slice.");
analyze_slice(&xs);
// Los slices pueden apuntar a una sección de un arreglo.
// Estos son de la forma [índice_inicial..índice_final].
// `índice_inicial` es la primera posición en el slice.
// `índice_final` es uno más que la última posición en la porción.
println!("Hace Borrow de una sección del arreglo como un slice.");
analyze_slice(&ys[1 .. 4]);
// Un ejemplo de un slice vacío `&[]`:
let empty_array: [u32; 0] = [];
assert_eq!(&empty_array, &[]);
assert_eq!(&empty_array, &[][..]); // Lo mismo pero menos conciso
// Se pueden acceder a las arreglos de forma segura usando `.get`, el cual devuelve un
// `Option'. Aquí se puede usar un match como se muestra a continuación, o en su caso con
// `.expect()` si desees que el programa termine con un amable
// mensaje en lugar de continuar felizmente.
for i in 0..xs.len() + 1 { // ¡Oops!, un elemento de sobra.
match xs.get(i) {
Some(xval) => println!("{}: {}", i, xval),
None => println!("¡Para! {} es demasiado lejos", i),
}
}
// Usar un índice constante que se encuentra fuera del rango válido causa un error de compilación.
//println!("{}", xs[5]);
// Usar un índice fuera de rango en un slice causa un error de compilación.
//println!("{}", xs[..][5]);
}