El trait Debug
Parte de la sección Object Oriented Programming del Journey de Rust de Coddy — lección 35 de 61.
La biblioteca estándar de Rust viene con muchos traits predefinidos que proporcionan funcionalidad común. Uno de los más útiles para el desarrollo es el trait Debug, que permite imprimir el contenido de una estructura para su inspección.
Si intentas imprimir una estructura personalizada directamente, Rust no sabrá cómo mostrarla:
struct Player {
name: String,
score: u32,
}
let p = Player { name: String::from("Alice"), score: 100 };
println!("{:?}", p); // ¡Error! Debug no está implementado
El formateador {:?} requiere el trait Debug. En lugar de implementarlo manualmente, Rust proporciona un atajo: el atributo #[derive]. Colócalo directamente encima de la definición de tu struct:
#[derive(Debug)]
struct Player {
name: String,
score: u32,
}
let p = Player { name: String::from("Alice"), score: 100 };
println!("{:?}", p); // Player { name: "Alice", score: 100 }
El atributo #[derive(Debug)] le dice al compilador que genere automáticamente la implementación de Debug. Esto funciona siempre que todos los campos de tu struct también implementen Debug (lo cual hacen la mayoría de los tipos estándar).
Para una salida más legible con estructuras anidadas, utiliza {:#?} para una impresión estética (pretty-printing):
println!("{:#?}", p);
// Player {
// name: "Alice",
// score: 100,
// }
Derivar Debug es esencial durante el desarrollo: te permite inspeccionar rápidamente tus datos sin escribir código de formateo personalizado.
Desafío
Fácil¡Hagamos que tus structs sean inspeccionables derivando el trait Debug! Crearás un sistema de inventario sencillo donde los elementos se pueden imprimir para fines de depuración.
Organizarás tu código en dos archivos:
inventory.rs: Define una estructuraItempública con dos campos públicos:name(String) yquantity(u32). Utiliza el atributo#[derive(Debug)]para implementar automáticamente el trait Debug para tu struct.main.rs: Importa tu módulo inventory y crea una instancia deItemutilizando las entradas proporcionadas. Imprime el elemento usando el formateador de depuración{:?}para mostrar su estructura interna.
La belleza de derivar Debug es que Rust genera automáticamente el código de formateo por ti, ¡sin necesidad de implementación manual! Tu struct solo necesita el atributo y se vuelve imprimible con {:?}.
Tu salida debería mostrar el elemento en el formato de depuración de Rust:
Item { name: "{name}", quantity: {quantity} }Por ejemplo, con las entradas Keyboard y 15:
Item { name: "Keyboard", quantity: 15 }Recibirás dos entradas: el nombre del artículo (name) y la cantidad (quantity) (analízala como u32).
Pruébalo tú mismo
mod inventory;
use inventory::Item;
fn main() {
// Leer la entrada
let mut name = String::new();
std::io::stdin().read_line(&mut name).expect("Failed to read line");
let name = name.trim().to_string();
let mut quantity_str = String::new();
std::io::stdin().read_line(&mut quantity_str).expect("Failed to read line");
let quantity: u32 = quantity_str.trim().parse().expect("Failed to parse quantity");
// TODO: Crear una instancia de Item con el name y quantity dados
// TODO: Imprimir el item usando el formateador de depuración {:?}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Object Oriented Programming
1Métodos y Comportamiento
Intro a Bloques de ImplementaciónEl Parámetro SelfMétodos MutablesFunciones AsociadasMúltiples Bloques de ImplementaciónEncadenamiento de MétodosResumen - Acciones de Rectángulo4Proyecto: Mascota virtual
Definir la mascotaAlimentar a la mascota7Traits estándar
El trait DebugEl trait DisplayClone y CopyTraits de igualdadResumen - Punto imprimible10Proyecto: Sistema de documentos
El Trait DrawComponente de texto2Encapsulamiento y módulos
Conceptos básicos de módulosLa palabra clave PublicCampos privadosGettersSettersRepaso - Casillero seguro5Genéricos
Estructuras genéricasMétodos genéricosMúltiples tipos genéricosFunciones genéricasResumen - Punto de coordenadas8Traits como límites
Sintaxis de límites de traitsLímites múltiplesLa cláusula whereRetornar tipos con traitsResumen: Impresora genérica11Patrones de diseño en Rust
Patrón NewtypeComposiciónEl Trait DropFrom e IntoResumen - Mock de Smart Pointer3Enums avanzados
Enums con datosMétodos en EnumsCoincidencia de variantes de datosEl Enum Option revisitadoResumen - Enum Shape6Definición de Traits
¿Qué es un Trait?Implementación de TraitsImplementaciones por defectoSobrescribir valores por defectoTraits con parámetrosResumen - Reproductor multimedia