Il pattern Builder
Costruisca gli oggetti passo dopo passo.
Il pattern Builder è una lezione Learn Rust Coding gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Learn Rust Coding, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Learn Rust Coding include 4 lezioni in totale.
Perché un builder?
Rust non dispone di argomenti con nome o opzionali per le funzioni. Quando una struct ha molti campi, soprattutto opzionali, un costruttore con otto parametri posizionali diventa illeggibile e soggetto a errori.
Il pattern builder risolve questo problema. Configuri un oggetto passo dopo passo con metodi denominati, quindi chiami un build() finale per produrre il valore. Il risultato si legge come una frase fluida.
La struct di destinazione
Inizi dal tipo che desidera effettivamente costruire. Qui una configurazione del server contiene un host obbligatorio e diverse opzioni facoltative.
Noti che i campi sono privati, per incoraggiare la costruzione tramite il builder anziché tramite literal di struct.
pub struct ServerConfig {
host: String,
port: u16,
max_connections: usize,
use_tls: bool,
}Un tipo builder separato
L'approccio classico utilizza una seconda struct, il builder. Questa rispecchia la destinazione, ma memorizza lo stato di costruzione. I campi opzionali diventano spesso Option<T>, così è possibile distinguere tra "non impostato" e "impostato esplicitamente".
pub struct ServerConfigBuilder {
host: String,
port: Option<u16>,
max_connections: Option<usize>,
use_tls: bool,
}Avviare il builder
Fornisca al builder un costruttore che accetti solo i campi obbligatori. Tutto ciò che è opzionale inizia come None o con un valore predefinito.
Una convenzione comune consiste nell'aggiungere un metodo builder() al tipo di destinazione, che restituisca il builder.
impl ServerConfig {
pub fn builder(host: impl Into<String>) -> ServerConfigBuilder {
ServerConfigBuilder {
host: host.into(),
port: None,
max_connections: None,
use_tls: false,
}
}
}I setter prendono self per valore
Ogni setter consuma self, modifica un campo e restituisce self. Restituire il valore posseduto consente di concatenare le chiamate in modo fluido.
Questa concatenazione basata sulla proprietà è lo stile idiomatico di Rust ed evita complicazioni con i lifetime.
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
}
}Applicare i valori predefiniti in build()
Il build() terminale trasforma il builder nel tipo reale. È qui che si assegnano i valori predefiniti a tutto ciò che è ancora None, usando 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,
}
}
}Costruzione fluida
Ora la costruzione si legge dall'alto verso il basso. I dati obbligatori vengono passati a builder(); ogni modifica opzionale è una chiamata chiaramente denominata.
I campi omessi ricevono automaticamente i valori predefiniti.
fn main() {
let cfg = ServerConfig::builder("localhost")
.port(9000)
.use_tls(true)
.build();
println!("{}:{} tls={}", cfg.host, cfg.port, cfg.use_tls);
}Un esempio completo eseguibile
Ecco l'intero pattern condensato in un unico programma eseguibile. Mostra che i campi omessi ricevono i valori predefiniti all'interno di 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 fallibile con Result
A volte una configurazione può essere non valida, ad esempio quando la porta è zero. Faccia restituire a build() un Result, così gli errori di validazione emergono come errori recuperabili anziché come panic.
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 })
}
}Il crate derive_builder
Scrivere i builder manualmente è ripetitivo. Il crate derive_builder genera l'intero builder a partire da un'annotazione.
Annotando i campi con i valori predefiniti, ottiene automaticamente un FooBuilder generato, con setter e un build() fallibile.
use derive_builder::Builder;
#[derive(Builder)]
struct Channel {
#[builder(default = "8080")]
port: u16,
name: String,
}Builder con proprietà o con riferimento mutabile
Esistono due stili. Lo stile con proprietà consuma self e si concatena naturalmente. Lo stile &mut self restituisce &mut Self e consente di suddividere la costruzione tra più istruzioni senza riassegnare la variabile.
Lo stile con proprietà è più comune per una costruzione unica; quello mutabile è adatto alla configurazione condizionale nei cicli.
impl ServerConfigBuilder {
pub fn port_ref(&mut self, port: u16) -> &mut Self {
self.port = Some(port);
self
}
}Verifica rapida
Verifichi la Sua comprensione dello stile builder con self posseduto.
Riepilogo
Il pattern builder aggira l'assenza di argomenti opzionali in Rust. Un tipo builder conserva lo stato di costruzione, i setter consumano e restituiscono self per consentire la concatenazione e build() applica i valori predefiniti per produrre il valore finale.
Utilizzi Result in build() per la validazione e ricorra a derive_builder per evitare il codice ripetitivo.
Impara Rust con un tutor IA — gratis
Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.
- Corsi
- 39
- Lezioni
- 144
Domande Frequenti
La lezione «Il pattern Builder» è gratuita?
Sì — il testo completo di «Il pattern Builder» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Learn Rust Coding, passa a CoddyKit PRO. Il corso Learn Rust Coding include 4 lezioni in totale.
Cosa imparerò in «Il pattern Builder»?
Costruisca gli oggetti passo dopo passo. Eserciti Learn Rust Coding con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Learn Rust Coding?
Non è richiesta alcuna esperienza precedente. Learn Rust Coding su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.
Quanto tempo richiede la lezione «Il pattern Builder»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Learn Rust Coding?
Sì. Ogni lezione Learn Rust Coding include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.