Learn Rust Coding · Lección

El patrón Builder

Construya objetos paso a paso

Lección 1 de 413 pasos

El patrón Builder es una lección gratuita de Learn Rust Coding en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Learn Rust Coding, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Learn Rust Coding incluye 4 lecciones en total.

¿Por qué un Builder?

Rust no tiene argumentos de función con nombre ni opcionales. Cuando una estructura tiene muchos campos, especialmente opcionales, un constructor con ocho parámetros posicionales resulta difícil de leer y propenso a errores.

El patrón builder resuelve este problema. Configura un objeto paso a paso mediante métodos con nombre y, después, llama a un build() final para producir el valor. El código se lee como una frase fluida.

La estructura de destino

Comience por el tipo que realmente desea construir. Aquí, la configuración de un servidor contiene un host obligatorio y varias opciones configurables.

Observe que los campos son privados para fomentar la construcción mediante el builder en lugar de usar literales de estructura.

pub struct ServerConfig {
    host: String,
    port: u16,
    max_connections: usize,
    use_tls: bool,
}

Un tipo Builder independiente

El enfoque clásico utiliza una segunda estructura: el builder. Este refleja la estructura de destino, pero almacena el estado en proceso de construcción. Los campos opcionales suelen convertirse en Option<T> para poder distinguir entre «no establecido» y «establecido explícitamente».

pub struct ServerConfigBuilder {
    host: String,
    port: Option<u16>,
    max_connections: Option<usize>,
    use_tls: bool,
}

Iniciar el Builder

Proporcione al builder un constructor que acepte únicamente los campos obligatorios. Todo lo opcional comienza como None o con un valor predeterminado.

Una convención habitual consiste en definir un método builder() en el tipo de destino que devuelva el builder.

impl ServerConfig {
    pub fn builder(host: impl Into<String>) -> ServerConfigBuilder {
        ServerConfigBuilder {
            host: host.into(),
            port: None,
            max_connections: None,
            use_tls: false,
        }
    }
}

Los métodos setter reciben self por valor

Cada setter consume self, modifica un campo y devuelve self. Devolver el valor poseído permite encadenar llamadas de forma fluida.

Este encadenamiento basado en la propiedad es el estilo idiomático de Rust y evita complicaciones con los tiempos de vida.

impl ServerConfigBuilder {
    pub fn port(mut self, port: u16) -> Self {
        self.port = Some(port);
        self
    }
    pub fn use_tls(mut self, yes: bool) -> Self {
        self.use_tls = yes;
        self
    }
}

Aplicar valores predeterminados en build()

El build() final transforma el builder en el tipo real. Aquí es donde se asignan valores predeterminados a todo lo que siga siendo None mediante unwrap_or.

impl ServerConfigBuilder {
    pub fn build(self) -> ServerConfig {
        ServerConfig {
            host: self.host,
            port: self.port.unwrap_or(8080),
            max_connections: self.max_connections.unwrap_or(128),
            use_tls: self.use_tls,
        }
    }
}

Construcción fluida

Ahora la construcción se lee de arriba abajo. Los datos obligatorios se pasan a builder() y cada ajuste opcional se realiza mediante una llamada con un nombre claro.

Los campos que omita adoptan silenciosamente sus valores predeterminados.

fn main() {
    let cfg = ServerConfig::builder("localhost")
        .port(9000)
        .use_tls(true)
        .build();
    println!("{}:{} tls={}", cfg.host, cfg.port, cfg.use_tls);
}

Un ejemplo ejecutable completo

Aquí tiene el patrón completo, condensado en un único programa que puede ejecutar. Muestra que los campos omitidos recuperan sus valores predeterminados dentro de build().

struct Config { name: String, retries: u32 }
struct Builder { name: String, retries: Option<u32> }
impl Config {
    fn builder(name: &str) -> Builder {
        Builder { name: name.to_string(), retries: None }
    }
}
impl Builder {
    fn retries(mut self, n: u32) -> Self { self.retries = Some(n); self }
    fn build(self) -> Config {
        Config { name: self.name, retries: self.retries.unwrap_or(3) }
    }
}
fn main() {
    let c = Config::builder("job").build();
    println!("{} retries={}", c.name, c.retries);
}

build falible con Result

A veces una configuración puede ser no válida; por ejemplo, un puerto con valor cero. Haga que build() devuelva Result para que los errores de validación aparezcan como errores recuperables en lugar de producir panics.

impl ServerConfigBuilder {
    pub fn try_build(self) -> Result<ServerConfig, String> {
        let port = self.port.unwrap_or(8080);
        if port == 0 {
            return Err("port must be non-zero".into());
        }
        Ok(ServerConfig { host: self.host, port,
            max_connections: self.max_connections.unwrap_or(128),
            use_tls: self.use_tls })
    }
}

El crate derive_builder

Escribir builders manualmente resulta repetitivo. El crate derive_builder genera todo el builder a partir de una anotación.

Puede anotar los campos con valores predeterminados y obtener automáticamente un FooBuilder generado, con setters y un build() falible.

use derive_builder::Builder;

#[derive(Builder)]
struct Channel {
    #[builder(default = "8080")]
    port: u16,
    name: String,
}

Builders propietarios frente a builders con referencias mutables

Existen dos estilos. El estilo propietario consume self y se encadena de forma natural. El estilo &mut self devuelve &mut Self y permite repartir la construcción entre varias instrucciones sin volver a vincular la variable.

El estilo propietario es más habitual para construcciones de un solo uso; el estilo mutable resulta adecuado para configuraciones condicionales en bucles.

impl ServerConfigBuilder {
    pub fn port_ref(&mut self, port: u16) -> &mut Self {
        self.port = Some(port);
        self
    }
}

Comprobación rápida

Compruebe su comprensión del estilo de builder basado en self propietario.

Resumen

El patrón builder compensa la ausencia de argumentos opcionales en Rust. Un tipo builder almacena el estado en proceso de construcción, los setters consumen y devuelven self para permitir el encadenamiento, y build() aplica los valores predeterminados para producir el valor final.

Use Result en build() para realizar la validación y recurra a derive_builder para evitar el código repetitivo.

Gratis para empezar

Aprende Rust con un tutor de IA — gratis

Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.

Cursos
39
Lecciones
144

Preguntas frecuentes

¿La lección «El patrón Builder» es gratis?

Sí — el texto completo de «El patrón Builder» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Learn Rust Coding, actualiza a CoddyKit PRO. El curso de Learn Rust Coding incluye 4 lecciones en total.

¿Qué aprenderé en «El patrón Builder»?

Construya objetos paso a paso Practicas Learn Rust Coding con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Learn Rust Coding?

No se requiere experiencia previa. Learn Rust Coding en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «El patrón Builder»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Learn Rust Coding?

Sí. Cada lección de Learn Rust Coding incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. El patrón Builder
  2. El patrón Newtype
  3. Builders con estado de tipos
  4. Ergonomía de Deref y wrappers
← Volver a Learn Rust Coding