Impresión Formateada en Rust

RustRustBeginner
Practicar Ahora

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

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

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.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/MemorySafetyandManagementGroup(["Memory Safety and Management"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/DataTypesGroup -.-> rust/integer_types("Integer Types") rust/DataTypesGroup -.-> rust/floating_types("Floating-point Types") rust/DataTypesGroup -.-> rust/string_type("String Type") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/MemorySafetyandManagementGroup -.-> rust/lifetime_specifiers("Lifetime Specifiers") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99186{{"Impresión Formateada en Rust"}} rust/integer_types -.-> lab-99186{{"Impresión Formateada en Rust"}} rust/floating_types -.-> lab-99186{{"Impresión Formateada en Rust"}} rust/string_type -.-> lab-99186{{"Impresión Formateada en Rust"}} rust/function_syntax -.-> lab-99186{{"Impresión Formateada en Rust"}} rust/expressions_statements -.-> lab-99186{{"Impresión Formateada en Rust"}} rust/lifetime_specifiers -.-> lab-99186{{"Impresión Formateada en Rust"}} rust/operator_overloading -.-> lab-99186{{"Impresión Formateada en Rust"}} end

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.