Errore Rust E0027: pattern does not mention field X (campo mancante nel pattern)
E0027 significa: stai scomponendo una struct o una variante di enum con un pattern, come let Order { item, quantity } = order;, e non hai nominato tutti i campi. In Rust un pattern su una struct deve tenere conto di tutti i campi, nominandoli oppure dicendo «e tutto il resto» con ... È uno degli errori più gentili che ci siano: rustc stampa la correzione esatta, e quasi sempre sono due puntini. (Questa pagina fa parte di Errori del compilatore Rust spiegati.)
Il messaggio di errore
Sezione intitolata “Il messaggio di errore”error[E0027]: pattern does not mention fields `id`, `paid` --> src/main.rs:10:9 |10 | let Order { item, quantity } = order; // ❌ `id` and `paid` are not mentioned | ^^^^^^^^^^^^^^^^^^^^^^^^ missing fields `id`, `paid` |help: include the missing fields in the pattern |10 | let Order { item, quantity, id, paid } = order; // ❌ `id` and `paid` are not mentioned | ++++++++++help: if you don't care about these missing fields, you can explicitly ignore them |10 | let Order { item, quantity, id: _, paid: _ } = order; // ❌ `id` and `paid` are not mentioned | ++++++++++++++++help: or always ignore missing fields here |10 | let Order { item, quantity, .. } = order; // ❌ `id` and `paid` are not mentioned | ++++Il compilatore dice: il pattern non nomina i campi id e paid, e ti propone tre modi per sistemarlo. Questo è il programma che produce l’errore:
struct Order { id: u32, item: String, quantity: u32, paid: bool,}
fn main() { let order = Order { id: 1, item: String::from("keyboard"), quantity: 2, paid: true }; let Order { item, quantity } = order; // ❌ `id` and `paid` are not mentioned println!("{} x {}", quantity, item);}Cosa significa
Sezione intitolata “Cosa significa”La prima riga elenca i campi che il tuo pattern ha lasciato fuori (id e paid). Il ^^^ sottolinea tutto il pattern, perché il problema non è una parola sbagliata: è qualcosa che manca.
Poi rustc ti dà tre suggerimenti help:. Sono tutti validi, ma significano cose diverse:
include the missing fields(includi i campi mancanti): nominali, così ottieni anche le variabiliidepaid.explicitly ignore them(ignorali in modo esplicito): scriviid: _, paid: _. Non ottieni variabili, ma hai elencato ogni campo per nome.always ignore missing fields here(ignora sempre i campi mancanti qui): scrivi... Significa «e tutti gli altri campi, non mi interessano».
È come un modulo all’ingresso che dice «spunta ogni casella, oppure spunta Altro: salta». Non puoi lasciare caselle vuote.
Perché Rust si comporta così
Sezione intitolata “Perché Rust si comporta così”In Rust un pattern su una struct è pensato per essere completo, a meno che tu non dica il contrario. Così la tua intenzione è chiara a chi legge il codice dopo di te. Order { item, quantity, .. } dice «mi servono solo questi due». Order { id, item, quantity, paid } dice «ho pensato a ogni campo». Vedi Pattern matching in Rust.
Il vero vantaggio arriva quando la struct cambia. Se qualcuno aggiunge un campo discount a Order, un pattern che elenca ogni campo per nome si rompe con E0027, e ti indica il codice che forse deve gestire il nuovo campo. Un pattern con .. continua a compilare. Rust ti lascia scegliere il comportamento che vuoi, ma non lo indovina al posto tuo.
Come risolverlo
Sezione intitolata “Come risolverlo”Soluzione 1: aggiungi .. per ignorare il resto
Sezione intitolata “Soluzione 1: aggiungi .. per ignorare il resto”Scegli questa nella maggior parte dei casi. Se ti servono solo alcuni campi, chiudi il pattern con ... Funziona in let, match, if let e nei parametri delle funzioni, e deve stare per ultimo.
struct Order { id: u32, item: String, quantity: u32, paid: bool,}
fn main() { let order = Order { id: 1, item: String::from("tastiera"), quantity: 2, paid: true }; let Order { item, quantity, .. } = order; // ✅ `..` salta `id` e `paid` println!("{} x {}", quantity, item);
let orders = [ Order { id: 2, item: String::from("mouse"), quantity: 1, paid: false }, Order { id: 3, item: String::from("monitor"), quantity: 1, paid: true }, ]; for order in &orders { match order { Order { paid: true, item, .. } => println!("spedisci il {}", item), Order { id, .. } => println!("l'ordine #{} aspetta il pagamento", id), } }}Output:
2 x tastieral'ordine #2 aspetta il pagamentospedisci il monitorNota paid: true nel primo ramo: un campo in un pattern può anche essere confrontato con un valore, e .. continua a occuparsi degli altri.
Soluzione 2: nomina il campo mancante, o ignoralo per nome con _
Sezione intitolata “Soluzione 2: nomina il campo mancante, o ignoralo per nome con _”Scegli questa quando il campo ti serve davvero, o quando vuoi che il pattern si rompa se in futuro viene aggiunto un campo. Lo stesso errore compare in un match su una variante di enum con campi nominati:
error[E0027]: pattern does not mention field `y` --> src/main.rs:9:9 |9 | Message::Move { x } => println!("move to x = {}", x), // ❌ `y` is not mentioned | ^^^^^^^^^^^^^^^^^^^ missing field `y`Il programma che lo produce:
enum Message { Move { x: i32, y: i32 }, Quit,}
fn main() { let m = Message::Move { x: 1, y: 2 }; match m { Message::Move { x } => println!("move to x = {}", x), // ❌ `y` is not mentioned Message::Quit => println!("quit"), }}Uno spostamento ha due coordinate, e il codice dovrebbe proprio usarle entrambe. Quindi nomina y. Quando un campo davvero non conta, y: _ lo dice ad alta voce, e lo elenca comunque per nome:
enum Message { Move { x: i32, y: i32 }, Quit,}
fn main() { let messages = [Message::Move { x: 1, y: 2 }, Message::Move { x: 5, y: 0 }, Message::Quit]; for m in &messages { match m { Message::Move { x, y: 0 } => println!("scivola sul pavimento fino a x = {}", x), Message::Move { x, y } => println!("vai a ({}, {})", x, y), // ✅ tutti e due i campi Message::Quit => println!("esci"), } }
// ogni campo elencato per nome: aggiungere un campo a `Move` romperà questo di proposito if let Message::Move { x, y: _ } = &messages[0] { println!("primo x = {}", x); }}Output:
vai a (1, 2)scivola sul pavimento fino a x = 5esciprimo x = 1Se nomini un campo solo per ignorarlo, scrivi y: _, non un semplice y. Un y semplice che non usi mai ti dà un warning «unused variable» (variabile non usata).
Soluzione 3: correggi un nome di campo scritto male
Sezione intitolata “Soluzione 3: correggi un nome di campo scritto male”Scegli questa quando E0027 arriva insieme a E0026 sulla stessa riga. Per esempio, Shape::Circle { r } per una variante il cui campo si chiama radius li dà tutti e due: E0026 per r (campo inesistente) ed E0027 per radius (non nominato). Il suggerimento di E0027 ti proporrà di aggiungere radius accanto a r, ma non è quello che vuoi. La vera correzione è sostituire il nome sbagliato: Shape::Circle { radius }, oppure Shape::Circle { radius: r } per tenere il nome di variabile corto. Così spariscono entrambi gli errori in un colpo. Trovi esempi nella pagina su E0026.
Dove lo incontri di solito
Sezione intitolata “Dove lo incontri di solito”Dopo aver aggiunto un campo a una struct. Aggiungi created_at a Order, e ogni pattern che elencava tutti i campi ora dà E0027. È il controllo che fa il suo lavoro. Decidi caso per caso: questo codice ha bisogno di created_at? Se sì, nominalo; se no, aggiungi ...
Parametri di funzione. Anche fn print_order(&Order { item, quantity }: &Order) dà E0027. Correzione: &Order { item, quantity, .. }. Vedi Pattern matching in Rust.
Tuple struct e varianti tupla. Per struct Color(u8, u8, u8);, anche il pattern Color(r) è incompleto, ma rustc lo segnala come E0023, «this pattern has 1 field, but the corresponding tuple struct has 3 fields». La correzione segue la stessa idea: Color(r, ..) oppure Color(r, _, _).
Errori correlati
Sezione intitolata “Errori correlati”- E0026: struct or variant does not have a field named x: un nome di campo nel pattern che non esiste. Spesso compare insieme a E0027.
- E0063: missing field in initializer: la stessa idea quando crei una struct: ogni campo ha bisogno di un valore (o di
..Default::default()). - E0004: non-exhaustive patterns: un
matchche non copre ogni variante, mentre E0027 riguarda ogni campo. E0023: this pattern has N fields, but the corresponding tuple struct has M fields: la versione per le tuple struct (vedi sopra).- Tutti gli errori del compilatore spiegati
Verifica veloce
Sezione intitolata “Verifica veloce”Verifica veloce
1. struct Point { x: i32, y: i32, z: i32 }. Quale pattern compila e ti dà solo x?
2. Che differenza c'è tra Order { item, .. } e Order { item, id: _, quantity: _, paid: _ }?
3. Ricevi E0026 per r ed E0027 per radius sulla stessa riga. Qual è la correzione migliore?
Punteggio: 0 / 3
Per approfondire
Sezione intitolata “Per approfondire”- E0027 — Rust error codes index (in inglese): la spiegazione ufficiale di questo errore.
- Pattern Syntax — The Rust Book (in inglese): scomporre le struct e la sezione «Ignoring Remaining Parts of a Value with
..». - Destructuring structs — Rust by Example (in inglese): pattern sulle struct con
.., da eseguire. - Patterns — The Rust Reference (in inglese): le regole esatte dei pattern sulle struct e del rest pattern.