Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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]);
}