Errore Rust E0026: struct or variant does not have a field named X (campo inesistente nel pattern)
E0026 significa: stai scomponendo una struct o una variante di enum con un pattern, come Shape::Circle { r }, e uno dei nomi di campo che hai scritto non esiste. È la versione per i pattern di E0560 e E0559, che segnalano lo stesso sbaglio quando crei un valore. Di solito rustc ti dice il nome giusto in una riga help:, quindi spesso basta cambiare una sola parola. (Questa pagina fa parte di Errori del compilatore Rust spiegati.)
Il messaggio di errore
Sezione intitolata “Il messaggio di errore”error[E0026]: variant `Shape::Circle` does not have a field named `r` --> src/main.rs:8:25 |8 | Shape::Circle { r } => 3.14 * r * r, // ❌ the field is called `radius` | ^ | | | variant `Shape::Circle` does not have this field | help: `Shape::Circle` has a field named `radius`Il compilatore dice: la variante Shape::Circle non ha un campo chiamato r, mentre ne ha uno chiamato radius. Questo è il programma che produce l’errore:
enum Shape { Circle { radius: f64 }, Rectangle { width: f64, height: f64 },}
fn area(shape: &Shape) -> f64 { match shape { Shape::Circle { r } => 3.14 * r * r, // ❌ the field is called `radius` Shape::Rectangle { width, height } => width * height, }}
fn main() { println!("{}", area(&Shape::Circle { radius: 1.0 }));}Per la stessa riga vedrai anche un secondo errore: E0027, «pattern does not mention field radius» (il pattern non nomina il campo radius). È lo stesso sbaglio visto dall’altra parte. Rust ha trovato un campo che hai nominato ma che non esiste (r) e un campo vero che non hai nominato (radius). Correggi il nome e spariscono tutti e due.
Cosa significa
Sezione intitolata “Cosa significa”La prima riga nomina la struct o variante che stai confrontando (Shape::Circle) e il campo che hai scritto (r). Il ^ indica quel nome dentro le graffe del pattern.
In un pattern, i nomi dentro { } sono nomi di campo, non nomi di variabili nuove che scegli tu. Shape::Circle { r } è l’abbreviazione di Shape::Circle { r: r }: «prendi il campo chiamato r e mettilo in una variabile chiamata r». Circle non ha nessun campo r, quindi Rust si ferma.
Sotto la freccia, rustc ti dà uno di questi suggerimenti:
help: `Shape::Circle` has a field named `radius`: c’è esattamente un campo che non hai nominato, quindi rustc immagina che intendessi quello.help: a field with a similar name exists: un errore di battitura, comenmaeal posto diname. rustc ti mostra la riga corretta.- Nessun suggerimento: rustc non è riuscito a indovinare. Guarda la definizione della struct o dell’enum per trovare i nomi veri.
È come chiedere a un bibliotecario «il libro sullo scaffale Narrativa-più-o-meno». Lui capisce che vuoi uno scaffale, ma può andare solo a quelli che esistono davvero.
Perché Rust si comporta così
Sezione intitolata “Perché Rust si comporta così”Un pattern come Shape::Circle { radius } è una promessa: «quando il valore è un Circle, dammi il suo radius». Rust controlla questa promessa sulla definizione mentre compila, così un pattern non può mai chiedere dati che non ci sono. Vedi Pattern matching in Rust.
Nei linguaggi senza questo controllo, leggere una chiave che manca ti dà undefined o null, e il bug salta fuori molto più tardi, lontano dall’errore di battitura. In Rust l’errore di battitura non supera il compilatore. Ti protegge anche quando qualcuno rinomina un campo: ogni pattern che usa ancora il vecchio nome si accende con E0026, così nessuno viene dimenticato in silenzio.
Come risolverlo
Sezione intitolata “Come risolverlo”Soluzione 1: usa il nome vero del campo
Sezione intitolata “Soluzione 1: usa il nome vero del campo”Scegli questa nella maggior parte dei casi. Usa il nome che trovi nella riga help:, oppure guarda la definizione. I nomi dei campi distinguono maiuscole e minuscole e si scrivono in snake_case.
Un errore di battitura riceve il suggerimento «similar name» (nome simile) e la riga corretta:
error[E0026]: struct `User` does not have a field named `nmae` --> src/main.rs:8:16 |8 | let User { nmae, age } = user; // ❌ typo: the field is `name` | ^^^^ struct `User` does not have this field |help: a field with a similar name exists |8 - let User { nmae, age } = user; // ❌ typo: the field is `name`8 + let User { name, age } = user; // ❌ typo: the field is `name` |Il programma che lo produce:
struct User { name: String, age: u32,}
fn main() { let user = User { name: String::from("Ferris"), age: 7 }; let User { nmae, age } = user; // ❌ typo: the field is `name` println!("{} is {} years old", nmae, age);}Scrivi i nomi dei campi esattamente come nella definizione. Così l’abbreviazione funziona e ottieni variabili con gli stessi nomi:
struct User { name: String, age: u32,}
enum Shape { Circle { radius: f64 }, Rectangle { width: f64, height: f64 },}
fn area(shape: &Shape) -> f64 { match shape { Shape::Circle { radius } => 3.14 * radius * radius, // ✅ il nome vero del campo Shape::Rectangle { width, height } => width * height, }}
fn main() { let shapes = [ Shape::Circle { radius: 2.0 }, Shape::Rectangle { width: 3.0, height: 4.0 }, ]; for shape in &shapes { println!("area: {:.2}", area(shape)); }
let user = User { name: String::from("Ferris"), age: 7 }; let User { name, age } = user; // ✅ `name`, non `nmae` println!("{} ha {} anni", name, age);}Output:
area: 12.56area: 12.00Ferris ha 7 anniSoluzione 2: tieni il tuo nome di variabile con campo: nome
Sezione intitolata “Soluzione 2: tieni il tuo nome di variabile con campo: nome”Scegli questa quando il nome corto r ti piace e vuoi solo che la variabile si chiami così. Scrivi il nome vero del campo, i due punti e poi il nome della variabile: Shape::Circle { radius: r }. Leggilo come «prendi il campo radius e chiamalo r».
enum Shape { Circle { radius: f64 }, Rectangle { width: f64, height: f64 },}
fn area(shape: &Shape) -> f64 { match shape { Shape::Circle { radius: r } => 3.14 * r * r, // ✅ campo `radius`, variabile `r` Shape::Rectangle { width: w, height: h } => w * h, }}
fn main() { let small = Shape::Circle { radius: 1.0 }; let wide = Shape::Rectangle { width: 10.0, height: 2.5 }; println!("piccolo: {:.2}", area(&small)); println!("largo: {:.2}", area(&wide));}Output:
piccolo: 3.14largo: 25.00È comodo anche quando due campi andrebbero in conflitto con variabili che hai già, o quando il nome del campo è lungo.
Soluzione 3: controlla di confrontare la variante giusta
Sezione intitolata “Soluzione 3: controlla di confrontare la variante giusta”Scegli questa quando il campo che hai scritto esiste davvero, ma in una variante diversa. Ogni variante di un enum ha i suoi campi. Qui x appartiene a Click, ma il ramo confronta KeyPress:
error[E0026]: variant `Event::KeyPress` does not have a field named `x` --> src/main.rs:9:27 |9 | Event::KeyPress { x, .. } => format!("key at {}", x), // ❌ `x` belongs to `Click` | ^ | | | variant `Event::KeyPress` does not have this field | help: `Event::KeyPress` has a field named `key`Il programma che lo produce:
enum Event { Click { x: i32, y: i32 }, KeyPress { key: char },}
fn describe(event: &Event) -> String { match event { Event::Click { x, y } => format!("click at ({}, {})", x, y), Event::KeyPress { x, .. } => format!("key at {}", x), // ❌ `x` belongs to `Click` }}
fn main() { println!("{}", describe(&Event::KeyPress { key: 'a' }));}Il suggerimento di rustc (key) significa solo «l’unico campo che non hai nominato», quindi non seguirlo alla cieca. Chiediti che cosa deve fare questo ramo. La pressione di un tasto non ha una posizione, quindi qui la correzione giusta è usare il campo che KeyPress ha davvero:
enum Event { Click { x: i32, y: i32 }, KeyPress { key: char },}
fn describe(event: &Event) -> String { match event { Event::Click { x, y } => format!("clic in ({}, {})", x, y), Event::KeyPress { key } => format!("tasto '{}' premuto", key), // ✅ KeyPress ha `key` }}
fn main() { let events = [Event::Click { x: 10, y: 20 }, Event::KeyPress { key: 'a' }]; for event in &events { println!("{}", describe(event)); }}Output:
clic in (10, 20)tasto 'a' premutoSe la pressione di un tasto deve davvero avere una posizione, aggiungi invece i campi alla variante: KeyPress { key: char, x: i32, y: i32 }. Poi ogni punto che crea un KeyPress deve compilarli (rustc te li indica uno per uno con E0063).
Dove lo incontri di solito
Sezione intitolata “Dove lo incontri di solito”Dopo aver rinominato un campo. Hai rinominato r in radius nell’enum, e ogni ramo Shape::Circle { r } => ... ora dà E0026. Cerca il vecchio nome nel progetto e aggiorna ogni pattern, oppure usa radius: r per tenere il vecchio nome di variabile.
In if let e let. if let Some(User { nmae, .. }) = find_user() dà lo stesso errore. Aggiungere .. qui non aiuta: .. salta i campi che non nomini, ma ogni nome che scrivi deve comunque esistere. Correzione: User { name, .. }.
Graffe su una variante tupla o una tuple struct. Per struct Point(i32, i32);, il pattern Point { x, y } non ha nomi di campo veri da confrontare. rustc lo segnala con un codice diverso, E0769, «tuple variant Point written as struct variant», e suggerisce Point(x, y). Vedi Pattern matching in Rust.
Errori correlati
Sezione intitolata “Errori correlati”- E0027: pattern does not mention field: il gemello di E0026, un campo vero che il tuo pattern ha lasciato fuori. Spesso compare insieme a E0026.
- E0559: variant has no field named x: lo stesso nome sbagliato quando crei una variante di enum.
- E0560: struct has no field named x: lo stesso nome sbagliato quando crei una struct.
- E0609: no field on type: lo stesso nome sbagliato quando leggi un campo, come
user.nmae. - E0533: expected unit struct, unit variant or constant: la variante è giusta, ma il pattern ha la forma sbagliata (senza
{ }). - Tutti gli errori del compilatore spiegati
Verifica veloce
Sezione intitolata “Verifica veloce”Verifica veloce
1. Con enum Shape { Circle { radius: f64 } }, che cosa chiede il pattern Shape::Circle { r }?
2. Vuoi il campo radius in una variabile chiamata r. Quale pattern funziona?
3. User { nmae, .. } compila se il campo si chiama name?
Punteggio: 0 / 3
Per approfondire
Sezione intitolata “Per approfondire”- E0026 — Rust error codes index (in inglese): la spiegazione ufficiale di questo errore.
- Pattern Syntax — The Rust Book (in inglese): scomporre struct ed enum, compresi
campo: variabilee... - Destructuring structs — Rust by Example (in inglese): piccoli esempi eseguibili di pattern sulle struct.
- Patterns — The Rust Reference (in inglese): le regole esatte dei pattern sulle struct e dell’abbreviazione dei campi.