Entender la documentación de Rust

Es importante conocer cómo leer la documentación de Rust para poder comprender lo que otras personas han escrito. A continuación, se observan algunas cosas que es es conveniente conocer de la documentación de Rust:

assert_eq!

Como se ha visto, assert_eq! se utiliza durante las pruebas. Se pasan dos elementos y la aplicación entra en pánico si no son iguales entre sí. A continuación, se muestra un ejemplo simple en el que se necesita un número par.

fn main() {
    prints_number(56);
}

fn prints_number(input: i32) {
    assert_eq!(input % 2, 0); // el resto debe ser cero para que sea par.
                              // Si el resultado de number % 2 si no es 0, entra en pánico
    println!("El número no es impar. Es {}", input);
}

Puede que no se quiera usar assert_eq! en el código que se escriba, pero está en todas partes de la documentación de Rust. Esto es debido a que en un documento se requiera mucho espacio para usar println! para todo. Además, se necesitaría que los elementos dispusieran del rasgo Display o Debug para todo lo que se quiera imprimir. Por eso la documentación utiliza assert_eq!. El siguiente es un ejmpleo de https://doc.rust-lang.org/std/vec/struct.Vec.html que muestra cómo utilizar Vec:

fn main() {
    let mut vec = Vec::new();
    vec.push(1);
    vec.push(2);

    assert_eq!(vec.len(), 2);
    assert_eq!(vec[0], 1);

    assert_eq!(vec.pop(), Some(2));
    assert_eq!(vec.len(), 1);

    vec[0] = 7;
    assert_eq!(vec[0], 7);

    vec.extend([1, 2, 3].iter().copied());

    for x in &vec {
        println!("{}", x);
    }
    assert_eq!(vec, [7, 1, 2, 3]);
}

En estos ejemplos basta con leer assert_eq(a, b) como que "a es b". A continuación, se muestra el mismo ejemplo con comentarios que indican lo que significa cada fila.

fn main() {
    let mut vec = Vec::new();
    vec.push(1);
    vec.push(2);

    assert_eq!(vec.len(), 2); // "La longitud del vec es 2"
    assert_eq!(vec[0], 1); // "vec[0] es 1"

    assert_eq!(vec.pop(), Some(2)); // "Cuando se usa .pop(), se obtiene un Some()"
    assert_eq!(vec.len(), 1); // "La longitud del vec ahora es 1"

    vec[0] = 7;
    assert_eq!(vec[0], 7); // "Vec[0] es 7"

    vec.extend([1, 2, 3].iter().copied());

    for x in &vec {
        println!("{}", x);
    }
    assert_eq!(vec, [7, 1, 2, 3]); // "El vec contiene ahora [7, 1, 2, 3]"
}

Búsquedas

La barra superior en la documentación de Rust es la barra de búsqueda. Muestra los resultados según se teclea. Cuando se avanza en una página, la barra de búsqueda desaparece, pero si se pulsa la tecla s en el teclado vuelve a aparecer. Esto permite buscar algo de forma rápida.

El enlace [source]

Normalmente, el código de un método, struct, etc. No estará completo. Esto se debe a que normalmente no se necesita ver todo el código para conocer como funciona. De hecho, el código completo puede hacer más difícil entender el objetivo de una explicación. Pero si se quiere ver, se puede pulsar en [source] y se mostrará todo el código. Por ejemplo, en la página dedicada a String se ver la declaración de .with_capacity():

#![allow(unused)]
fn main() {
// 🚧
pub fn with_capacity(capacity: usize) -> String
}

Este método recibe un número y obtiene una String. Si se quiere conocer más, se puede pulsar en el enlace [source] que muestra:

#![allow(unused)]
fn main() {
// 🚧
pub fn with_capacity(capacity: usize) -> String {
    String { vec: Vec::with_capacity(capacity) }
}
}

Ahora se puede observar que una String es un tipo de Vec. Realmente, un String es un vector de u8 bytes, lo que resulta interesante conocer. Para utilizar el método with_capacity no es necesario conocer este detalle, por eso solo se ve si se pulsa [source]. Así que es una buena idea pulsarlo cuando se quiere conocer los detalles de algo en la documentación.

Información sobre rasgos

La parte importante de la documentación de los rasgos es la de los "Métodos necesitados" (Required Methods) a la izquierda. Cuando en un rasgo existe un apartado a la izquierda con métodos necesitados, es probable que signifique que es necesario escribirlos. Por ejemplo, para Iterator se necesita escribir el método .next(). Y para el rasgo From se necesita escribir el método .from(). Algunos rasgos se pueden implementar con solo utilizar un atributo, como sucede con el rasgo Debug que basta con usar #[derive(Debug)]. Debug necesita el método .fmt(), pero normalmente no es necesario escribirlo ya que el atributo #[derive(Debug)] resulta suficiente para ello. Por eso, la página de std::fmt::Debug dice que "en general, debería ser suficiente con derivar la implementación de Debug".