El trait Display
Parte de la sección Object Oriented Programming del Journey de Rust de Coddy — lección 36 de 61.
Mientras que Debug es ideal para desarrolladores que inspeccionan datos, el trait Display está diseñado para salida orientada al usuario. Es lo que potencia el formateador {} en println!. A diferencia de Debug, Rust no puede derivar automáticamente Display—debes implementarlo manualmente.
Para implementar Display, necesitas importar el módulo fmt e implementar el método fmt:
use std::fmt;
struct Temperature {
celsius: f64,
}
impl fmt::Display for Temperature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}°C", self.celsius)
}
}
El método fmt recibe un Formatter y devuelve un fmt::Result. Usa la macro write! para formatear tu salida, accediendo a los campos de la estructura a través de self.
Ahora puedes imprimir la estructura con el formateador estándar {}:
let temp = Temperature { celsius: 23.5 };
println!("{}", temp); // 23.5°C
La diferencia clave: la salida Debug muestra la estructura de tus datos (útil para la depuración), mientras que la salida Display está pulida y pensada para los usuarios finales. Una estructura puede implementar ambas; usa {:?} para la depuración y {} para una salida limpia.
Desafío
Fácil¡Vamos a crear un sistema de visualización de productos fácil de usar! Mientras que Debug muestra la estructura bruta de tus datos, el trait Display te permite crear una salida pulida y legible para humanos, perfecta para los usuarios finales.
Organizarás tu código en dos archivos:
product.rs: Define una estructuraProductpública con dos campos públicos:name(String) yprice(f64). Implementa el traitDisplaypara tu estructura de modo que se formatee como{name} - ${price}. Recuerda importarstd::fmty usar la macrowrite!dentro de tu métodofmt.main.rs: Importa tu módulo product y crea una instancia deProductutilizando las entradas proporcionadas. Imprime el producto usando el formateador estándar{}para mostrar tu salida de visualización personalizada.
El trait Display requiere que implementes el método fmt manualmente; Rust no puede derivarlo automáticamente como Debug. Esto te da un control total sobre cómo aparece tu tipo ante los usuarios.
Tu salida debe mostrar el producto en un formato limpio y fácil de usar:
{name} - ${price}Por ejemplo, con las entradas Wireless Mouse y 29.99:
Wireless Mouse - $29.99Recibirás dos entradas: el nombre del producto y el precio (analizado como f64).
Hoja de referencia
El trait Display está diseñado para salida orientada al usuario y potencia el formateador {} en println!. A diferencia de Debug, debe implementarse manualmente.
Para implementar Display, importa el módulo fmt e implementa el método fmt:
use std::fmt;
struct Temperature {
celsius: f64,
}
impl fmt::Display for Temperature {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}°C", self.celsius)
}
}
El método fmt recibe un Formatter y devuelve un fmt::Result. Usa la macro write! para formatear la salida, accediendo a los campos de la estructura a través de self.
Imprime la estructura con el formateador {}:
let temp = Temperature { celsius: 23.5 };
println!("{}", temp); // 23.5°C
Diferencia clave: Debug ({:?}) muestra la estructura de datos para la depuración, mientras que Display ({}) proporciona una salida pulida para los usuarios finales.
Pruébalo tú mismo
mod product;
use product::Product;
fn main() {
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 price_input = String::new();
std::io::stdin().read_line(&mut price_input).expect("Failed to read line");
let price: f64 = price_input.trim().parse().expect("Failed to parse price");
// TODO: Crear una instancia de Product con el nombre y el precio
// TODO: Imprimir el producto usando el formateador {}
}
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