Menu
Coddy logo textTech

Sobrescribir valores por defecto

Parte de la sección Object Oriented Programming del Journey de Rust de Coddy — lección 32 de 61.

Las implementaciones por defecto son convenientes, pero a veces un tipo necesita un comportamiento que difiere del estándar. Cuando esto sucede, puedes sobrescribir el comportamiento por defecto proporcionando tu propia implementación en el bloque impl.

Simplemente define el método con la misma firma, pero incluye tu lógica personalizada:

trait Greet {
    fn greet(&self) -> String {
        String::from("Hello there!")
    }
}

struct Robot {
    id: u32,
}

impl Greet for Robot {
    fn greet(&self) -> String {
        format!("BEEP BOOP. Unit {} online.", self.id)
    }
}

Aunque Greet proporciona un método greet predeterminado, Robot lo reemplaza por completo con su propia versión. Cuando llamas a greet() en un Robot, Rust utiliza la implementación personalizada:

let bot = Robot { id: 42 };
println!("{}", bot.greet());  // BEEP BOOP. Unidad 42 en línea.

Esto te brinda flexibilidad: los tipos que están conformes con el comportamiento predeterminado no necesitan escribir nada, mientras que los tipos que necesitan un comportamiento especializado pueden sobrescribir solo los métodos que les interesan. El trait sigue garantizando que cada tipo que lo implemente tenga el método disponible.

challenge icon

Desafío

Fácil

¡Vamos a construir un sistema de notificaciones donde diferentes tipos de alerta puedan personalizar sus mensajes! Crearás un trait con una implementación por defecto, luego harás que un tipo use el valor por defecto mientras que otro lo sobrescribe con un comportamiento personalizado.

Organizarás tu código en tres archivos:

  • notifiable.rs: Define un trait público Notifiable con un método notify(&self) -> String que tenga una implementación por defecto que devuelva "Alert: Something happened!".
  • alerts.rs: Crea dos structs públicos que implementen tu trait de manera diferente:
    • GenericAlert — un unit struct que utiliza la notificación por defecto (bloque impl vacío).
    • UrgentAlert — un struct con un campo público message (String) que sobrescribe el comportamiento por defecto para devolver "URGENT: {message}" donde {message} es su mensaje almacenado.
  • main.rs: Une tus módulos y demuestra ambos comportamientos. Crea un GenericAlert y un UrgentAlert utilizando la entrada proporcionada, luego imprime sus notificaciones.

La idea clave aquí es que GenericAlert obtiene el comportamiento gratuito del valor por defecto, mientras que UrgentAlert proporciona su propia versión especializada al definir el método en su bloque impl.

Tu salida debe seguir este formato:

Alert: Something happened!
URGENT: {message}

Por ejemplo, con la entrada Server is down!:

Alert: Something happened!
URGENT: Server is down!

Recibirás una entrada: el mensaje para la alerta urgente.

Hoja de referencia

Puedes sobrescribir las implementaciones predeterminadas de los traits proporcionando tu propia implementación en el bloque impl:

trait Greet {
    fn greet(&self) -> String {
        String::from("Hello there!")
    }
}

struct Robot {
    id: u32,
}

impl Greet for Robot {
    fn greet(&self) -> String {
        format!("BEEP BOOP. Unit {} online.", self.id)
    }
}

let bot = Robot { id: 42 };
println!("{}", bot.greet());  // BEEP BOOP. Unit 42 online.

Los tipos que no necesitan un comportamiento personalizado pueden usar un bloque impl vacío para aceptar la implementación predeterminada, mientras que los tipos que requieren un comportamiento especializado pueden sobrescribir métodos específicos definiéndolos con la misma firma.

Pruébalo tú mismo

mod notifiable;
mod alerts;

use alerts::{GenericAlert, UrgentAlert};
use notifiable::Notifiable;

fn main() {
    // Leer la entrada para el mensaje de alerta urgente
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let message = input.trim().to_string();

    // TODO: Crear una instancia de GenericAlert

    // TODO: Crear una instancia de UrgentAlert con el mensaje de entrada

    // TODO: Imprimir la notificación de GenericAlert

    // TODO: Imprimir la notificación de UrgentAlert
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Object Oriented Programming