Impresión Formateada en Rust

Beginner

This tutorial is from open-source community. Access the source code

Introducción

En este laboratorio, se explica la funcionalidad de impresión formateada en Rust. El módulo std::fmt proporciona macros como format!, print!, println!, eprint! y eprintln! para manejar tareas de impresión. Estas macros permiten formatear texto con marcadores de posición que se reemplazan con los argumentos correspondientes. Se pueden utilizar argumentos posicionales y con nombre, y se pueden aplicar diferentes formatos utilizando caracteres de formato. Las macros también admiten la justificación del texto, el relleno de números y la fijación de la precisión para números decimales. El trato fmt::Display se utiliza para formatear texto de manera amigable para el usuario, mientras que el trato fmt::Debug se utiliza con fines de depuración. Rust también comprueba la corrección del formato en tiempo de compilación. Además, se menciona que implementar el trato fmt::Display implementa automáticamente el trato ToString, y los tipos personalizados deben implementar el trato fmt::Display para ser imprimibles. El laboratorio también incluye actividades para practicar el uso de las macros y los tratados de impresión formateada.

Nota: Si el laboratorio no especifica un nombre de archivo, puede utilizar cualquier nombre de archivo que desee. Por ejemplo, puede utilizar main.rs, compilar y ejecutarlo con rustc main.rs &&./main.

Impresión formateada

La impresión se maneja mediante una serie de macros definidas en std::fmt, algunas de las cuales son las siguientes:

  • format!: escribe texto formateado en String.
  • print!: es igual a format!, pero el texto se imprime en la consola (io::stdout).
  • println!: es igual a print!, pero se agrega una nueva línea al final.
  • eprint!: es igual a print!, pero el texto se imprime en el error estándar (io::stderr).
  • eprintln!: es igual a eprint!, pero se agrega una nueva línea al final.

Todas analizan el texto de la misma manera. Además, Rust comprueba la corrección del formato en tiempo de compilación.

fn main() {
    // En general, `{}` se reemplazará automáticamente con cualquier
    // argumento. Estos se convertirán en cadenas.
    println!("{} días", 31);

    // Se pueden utilizar argumentos posicionales. Especificar un entero dentro de `{}`
    // determina qué argumento adicional se reemplazará. Los argumentos empiezan
    // en 0 inmediatamente después de la cadena de formato.
    println!("{0}, esto es {1}. {1}, esto es {0}", "Alice", "Bob");

    // También se pueden utilizar argumentos con nombre.
    println!("{subject} {verb} {object}",
             object="el perro perezoso",
             subject="el rápido zorro marrón",
             verb="salta sobre");

    // Se puede invocar un formato diferente especificando el carácter de formato
    // después de un `:`.
    println!("Base 10:               {}",   69420); // 69420
    println!("Base 2 (binaria):       {:b}", 69420); // 10000111100101100
    println!("Base 8 (octal):        {:o}", 69420); // 207454
    println!("Base 16 (hexadecimal): {:x}", 69420); // 10f2c
    println!("Base 16 (hexadecimal): {:X}", 69420); // 10F2C

    // Puedes justificar el texto a la derecha con un ancho especificado. Esto
    // imprimirá "    1". (Cuatro espacios en blanco y un "1", para un ancho total de 5.)
    println!("{number:>5}", number=1);

    // Puedes rellenar los números con ceros adicionales,
    println!("{number:0>5}", number=1); // 00001
    // y ajustar a la izquierda invirtiendo el signo. Esto imprimirá "10000".
    println!("{number:0<5}", number=1); // 10000

    // Puedes utilizar argumentos con nombre en el especificador de formato agregando un `$`.
    println!("{number:0>width$}", number=1, width=5);

    // Rust incluso comprueba para asegurarse de que se utilicen el número correcto de argumentos.
    println!("Mi nombre es {0}, {1} {0}", "Bond");
    // FIXME ^ Agrega el argumento faltante: "James"

    // Solo los tipos que implementan fmt::Display se pueden formatear con `{}`. Los tipos
    // definidos por el usuario no implementan fmt::Display por defecto.

    #[allow(dead_code)] // desactiva `dead_code` que advierte sobre el módulo no utilizado
    struct Structure(i32);

    // Esto no se compilará porque `Structure` no implementa
    // fmt::Display.
    // println!("Esta struct `{}` no se imprimirá...", Structure(3));
    // TODO ^ Intenta descomentar esta línea

    // Para Rust 1.58 y superior, puedes capturar directamente el argumento de una
    // variable circundante. Al igual que lo anterior, esto imprimirá
    // "    1", 4 espacios en blanco y un "1".
    let number: f64 = 1.0;
    let width: usize = 5;
    println!("{number:>width$}");
}

std::fmt contiene muchos traits que gobiernan la visualización del texto. A continuación, se enumeran las formas básicas de dos de los más importantes:

  • fmt::Debug: utiliza el marcador {:?}. Formatea texto con fines de depuración.
  • fmt::Display: utiliza el marcador {}. Formatea texto de manera más elegante y amigable para el usuario.

Aquí, usamos fmt::Display porque la biblioteca estándar de Rust proporciona implementaciones para estos tipos. Para imprimir texto de tipos personalizados, se requieren más pasos.

Implementar el trato fmt::Display implementa automáticamente el trato ToString que nos permite convertir el tipo a String.

En la línea 43, #[allow(dead_code)] es un [atributo] que solo se aplica al módulo posterior a él.

Actividades

  • Corrige el problema en el código anterior (ver FIXME) para que se ejecute sin errores.
  • Intenta descomentar la línea que intenta formatear la struct Structure (ver TODO)
  • Agrega una llamada a la macro println! que imprima: Pi es aproximadamente 3.142 controlando el número de decimales mostrados. Con fines de este ejercicio, utiliza let pi = 3.141592 como una estimación de pi. (Pista: es posible que necesites revisar la documentación de std::fmt para establecer el número de decimales a mostrar)

Resumen

¡Felicidades! Has completado el laboratorio de Impresión Formateada. Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.