Encadenamiento de Métodos
Parte de la sección Object Oriented Programming del Journey de Rust de Coddy — lección 6 de 61.
Hasta ahora, nuestros métodos mutables han modificado la estructura y no han devuelto nada. ¿Pero qué pasa si queremos llamar a varios métodos seguidos en la misma instancia? Al devolver una referencia a self, habilitamos el encadenamiento de métodos, un patrón donde múltiples llamadas a métodos fluyen juntas en una sola expresión.
La clave es que tus métodos &mut self devuelvan &mut Self:
struct Config {
debug: bool,
timeout: u32,
}
impl Config {
fn new() -> Config {
Config { debug: false, timeout: 30 }
}
fn set_debug(&mut self, value: bool) -> &mut Self {
self.debug = value;
self
}
fn set_timeout(&mut self, seconds: u32) -> &mut Self {
self.timeout = seconds;
self
}
}
Cada método modifica la estructura y luego devuelve self—una referencia mutable de vuelta a la misma instancia. Esto permite que la siguiente llamada al método continúe trabajando en ella inmediatamente:
fn main() {
let mut config = Config::new();
config.set_debug(true).set_timeout(60);
println!("Debug: {}, Timeout: {}", config.debug, config.timeout);
// Salida: Debug: true, Timeout: 60
}
En lugar de escribir tres sentencias separadas, configuramos todo en una sola línea fluida. Este patrón de "estilo constructor" es especialmente útil al configurar objetos con muchos ajustes opcionales, lo que hace que el código sea más conciso y legible.
Desafío
FácilCrea una estructura TextStyle con tres campos: bold (bool), italic (bool), y size (u32).
Añade un bloque de implementación para TextStyle con lo siguiente:
new— una función asociada que devuelve unTextStyleconboldestablecido enfalse,italicenfalse, ysizeen12set_bold— toma&mut selfy un valorbool, establece el campo bold y devuelve&mut Selfpara el encadenamiento de métodosset_italic— toma&mut selfy un valorbool, establece el campo italic y devuelve&mut Selfpara el encadenamiento de métodosset_size— toma&mut selfy un valoru32, establece el campo size y devuelve&mut Selfpara el encadenamiento de métodos
Recibirás tres entradas:
- Primera línea: configuración de negrita (
trueofalse) - Segunda línea: configuración de cursiva (
trueofalse) - Tercera línea: tamaño de fuente (u32)
Crea un TextStyle mutable usando new, luego usa el encadenamiento de métodos para aplicar las tres configuraciones en una sola expresión. Imprime el estado final en el formato que se muestra a continuación.
Formato de salida esperado:
Bold: {bold}, Italic: {italic}, Size: {size}Hoja de referencia
Los métodos que toman &mut self pueden devolver &mut Self para permitir el encadenamiento de métodos:
impl Config {
fn set_debug(&mut self, value: bool) -> &mut Self {
self.debug = value;
self
}
fn set_timeout(&mut self, seconds: u32) -> &mut Self {
self.timeout = seconds;
self
}
}
Esto permite múltiples llamadas a métodos en una sola expresión:
let mut config = Config::new();
config.set_debug(true).set_timeout(60);
Cada método modifica la estructura y devuelve una referencia mutable a la misma instancia, permitiendo que el siguiente método continúe trabajando en ella inmediatamente.
Pruébalo tú mismo
use std::io;
// TODO: Define la estructura TextStyle aquí
// TODO: Añade el bloque de implementación para TextStyle con:
// - función asociada new()
// - método set_bold()
// - método set_italic()
// - método set_size()
fn main() {
let mut input = String::new();
// Leer configuración de negrita
io::stdin().read_line(&mut input).expect("Failed to read line");
let bold: bool = input.trim().parse().expect("Invalid bool");
input.clear();
// Leer configuración de cursiva
io::stdin().read_line(&mut input).expect("Failed to read line");
let italic: bool = input.trim().parse().expect("Invalid bool");
input.clear();
// Leer configuración de tamaño
io::stdin().read_line(&mut input).expect("Failed to read line");
let size: u32 = input.trim().parse().expect("Invalid u32");
// TODO: Crear un TextStyle mutable usando new(), luego usar encadenamiento de métodos
// para aplicar las tres configuraciones en una sola expresión
// TODO: Imprimir el resultado en el formato: Bold: {bold}, Italic: {italic}, Size: {size}
}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