Rust-Fehler E0027: pattern does not mention field X (Feld fehlt im Muster)
E0027 bedeutet: Du nimmst ein Struct oder eine Enum-Variante mit einem Muster (Pattern) auseinander, etwa let Order { item, quantity } = order;, und hast nicht jedes Feld erwähnt. In Rust muss ein Struct-Muster alle Felder berücksichtigen: Entweder du nennst sie, oder du sagst mit .. „und der Rest“. Das ist einer der freundlichsten Fehler überhaupt: rustc gibt dir die genaue Lösung aus, und fast immer sind es zwei Punkte. (Diese Seite gehört zur Reihe Rust-Compilerfehler einfach erklärt.)
Die Fehlermeldung
Abschnitt betitelt „Die Fehlermeldung“error[E0027]: pattern does not mention fields `id`, `paid` --> src/main.rs:10:9 |10 | let Order { item, quantity } = order; // ❌ `id` und `paid` werden nicht erwähnt | ^^^^^^^^^^^^^^^^^^^^^^^^ missing fields `id`, `paid` |help: include the missing fields in the pattern |10 | let Order { item, quantity, id, paid } = order; // ❌ `id` und `paid` werden nicht erwähnt | ++++++++++help: if you don't care about these missing fields, you can explicitly ignore them |10 | let Order { item, quantity, id: _, paid: _ } = order; // ❌ `id` und `paid` werden nicht erwähnt | ++++++++++++++++help: or always ignore missing fields here |10 | let Order { item, quantity, .. } = order; // ❌ `id` und `paid` werden nicht erwähnt | ++++Auf Deutsch: „Das Muster erwähnt die Felder id und paid nicht.“ Die Markierung sagt „fehlende Felder id, paid“.
Dieses Programm erzeugt den Fehler:
struct Order { id: u32, item: String, quantity: u32, paid: bool,}
fn main() { let order = Order { id: 1, item: String::from("Tastatur"), quantity: 2, paid: true }; let Order { item, quantity } = order; // ❌ `id` und `paid` werden nicht erwähnt println!("{} x {}", quantity, item);}Was sie bedeutet
Abschnitt betitelt „Was sie bedeutet“Die Überschrift zählt die Felder auf, die dein Muster weggelassen hat (id und paid). Das ^^^ unterstreicht das ganze Muster. Das Problem ist nämlich kein falsches Wort, sondern etwas, das fehlt.
Dann gibt dir rustc drei help:-Vorschläge. Alle drei sind gültig, aber sie bedeuten Verschiedenes:
include the missing fields(die fehlenden Felder aufnehmen): Nenn sie, dann bekommst du auch Variablenidundpaid.explicitly ignore them(sie ausdrücklich ignorieren): Schreibid: _, paid: _. Du bekommst keine Variablen, hast aber jedes Feld mit Namen aufgeführt.always ignore missing fields here(fehlende Felder hier immer ignorieren): Schreib... Das heißt „und alle anderen Felder, die sind mir egal“.
Das ist wie eine Checkliste an der Tür, auf der steht: „Hake jedes Kästchen ab, oder hake Sonstiges: überspringen ab.“ Kästchen einfach leer lassen geht nicht.
Warum Rust das macht
Abschnitt betitelt „Warum Rust das macht“Ein Struct-Muster soll in Rust vollständig sein, solange du nichts anderes sagst. So ist deine Absicht für den nächsten Leser klar. Order { item, quantity, .. } sagt „ich brauche nur diese zwei“. Order { id, item, quantity, paid } sagt „ich habe an jedes Feld gedacht“. Siehe Teile ignorieren mit _ und ...
Der eigentliche Gewinn zeigt sich, wenn sich das Struct ändert. Fügt jemand ein Feld discount zu Order hinzu, bricht ein Muster, das jedes Feld mit Namen aufführt, mit E0027 ab. Damit zeigt es dir Code, der das neue Feld vielleicht behandeln muss. Ein Muster mit .. kompiliert weiter. Rust lässt dich wählen, welches Verhalten du willst, aber es rät nicht für dich.
So behebst du den Fehler
Abschnitt betitelt „So behebst du den Fehler“Lösung 1: .. ergänzen, um den Rest zu ignorieren
Abschnitt betitelt „Lösung 1: .. ergänzen, um den Rest zu ignorieren“Nimm diese Lösung in den meisten Fällen. Brauchst du nur einige Felder, beende das Muster mit ... Das funktioniert in let, match, if let und in Funktionsparametern, und es muss am Ende stehen.
struct Order { id: u32, item: String, quantity: u32, paid: bool,}
fn main() { let order = Order { id: 1, item: String::from("Tastatur"), quantity: 2, paid: true }; let Order { item, quantity, .. } = order; // ✅ `..` überspringt `id` und `paid` println!("{} x {}", quantity, item);
let orders = [ Order { id: 2, item: String::from("Maus"), 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!("{} wird versendet", item), Order { id, .. } => println!("Bestellung #{} wartet auf die Zahlung", id), } }}Ausgabe:
2 x TastaturBestellung #2 wartet auf die ZahlungMonitor wird versendetAchte auf paid: true im ersten Zweig: Ein Feld in einem Muster kann auch mit einem Wert verglichen werden, und .. kümmert sich trotzdem um die anderen.
Lösung 2: Das fehlende Feld nennen oder mit _ namentlich ignorieren
Abschnitt betitelt „Lösung 2: Das fehlende Feld nennen oder mit _ namentlich ignorieren“Nimm diese Lösung, wenn du das Feld tatsächlich brauchst, oder wenn das Muster absichtlich brechen soll, sobald später ein Feld dazukommt. Derselbe Fehler erscheint bei einem match auf eine Enum-Variante mit benannten Feldern:
error[E0027]: pattern does not mention field `y` --> src/main.rs:9:9 |9 | Message::Move { x } => println!("bewege nach x = {}", x), // ❌ `y` wird nicht erwähnt | ^^^^^^^^^^^^^^^^^^^ missing field `y`Das Programm dazu:
enum Message { Move { x: i32, y: i32 }, Quit,}
fn main() { let m = Message::Move { x: 1, y: 2 }; match m { Message::Move { x } => println!("bewege nach x = {}", x), // ❌ `y` wird nicht erwähnt Message::Quit => println!("beenden"), }}Eine Bewegung hat zwei Koordinaten, und der Code sollte eigentlich beide benutzen. Nenn also y. Ist ein Feld wirklich egal, sagt y: _ das laut und deutlich und führt das Feld trotzdem mit Namen auf:
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!("über den Boden gleiten bis x = {}", x), Message::Move { x, y } => println!("bewege nach ({}, {})", x, y), // ✅ beide Felder Message::Quit => println!("beenden"), } }
// jedes Feld mit Namen: Ein neues Feld in `Move` lässt das hier absichtlich brechen if let Message::Move { x, y: _ } = &messages[0] { println!("erstes x = {}", x); }}Ausgabe:
bewege nach (1, 2)über den Boden gleiten bis x = 5beendenerstes x = 1Nennst du ein Feld nur, um es zu ignorieren, schreib y: _ und kein einfaches y. Ein einfaches y, das du nie benutzt, ergibt eine Warnung „unused variable“ (unbenutzte Variable).
Lösung 3: Einen falsch geschriebenen Feldnamen korrigieren
Abschnitt betitelt „Lösung 3: Einen falsch geschriebenen Feldnamen korrigieren“Nimm diese Lösung, wenn E0027 zusammen mit E0026 in derselben Zeile kommt. Zum Beispiel ergibt Shape::Circle { r } bei einer Variante, deren Feld radius heißt, beide: E0026 für r (kein solches Feld) und E0027 für radius (nicht erwähnt). Die Hilfe von E0027 schlägt dann vor, radius neben r zu ergänzen, aber das willst du nicht. Die eigentliche Lösung ist, den falschen Namen zu ersetzen: Shape::Circle { radius }, oder Shape::Circle { radius: r }, um den kurzen Variablennamen zu behalten. Dann verschwinden beide Fehler auf einmal. Beispiele findest du auf der Seite zu E0026.
Wo du ihn oft siehst
Abschnitt betitelt „Wo du ihn oft siehst“Nachdem du einem Struct ein Feld hinzugefügt hast. Du ergänzt created_at in Order, und jedes Muster, das alle Felder aufgeführt hat, meldet jetzt E0027. Genau dafür ist die Prüfung da. Entscheide für jedes Muster: Braucht dieser Code created_at? Wenn ja, nenn es; wenn nicht, ergänze ...
Funktionsparameter. Auch fn print_order(&Order { item, quantity }: &Order) ergibt E0027. Lösung: &Order { item, quantity, .. }. Siehe Muster in let und in Funktionsparametern.
Tupel-Structs und Tupel-Varianten. Bei struct Color(u8, u8, u8); ist auch das Muster Color(r) unvollständig, aber rustc meldet das als E0023, „this pattern has 1 field, but the corresponding tuple struct has 3 fields“ (dieses Muster hat 1 Feld, das Tupel-Struct hat aber 3). Die Lösung folgt derselben Idee: Color(r, ..) oder Color(r, _, _).
Verwandte Fehler
Abschnitt betitelt „Verwandte Fehler“- E0026: struct or variant does not have a field named x: ein Feldname im Muster, den es nicht gibt. Erscheint oft zusammen mit E0027.
- E0063: missing field in initializer: dieselbe Idee beim Erzeugen eines Structs: Jedes Feld braucht einen Wert (oder
..Default::default()). - E0004: non-exhaustive patterns: ein
match, das nicht jede Variante abdeckt, während es bei E0027 um jedes Feld geht. E0023: this pattern has N fields, but the corresponding tuple struct has M fields: die Version für Tupel-Structs (siehe oben).- Alle Compilerfehler einfach erklärt
Kurzer Check
Abschnitt betitelt „Kurzer Check“Kurzer Check
1. struct Point { x: i32, y: i32, z: i32 }. Welches Muster kompiliert und gibt dir nur x?
2. Was ist der Unterschied zwischen Order { item, .. } und Order { item, id: _, quantity: _, paid: _ }?
3. Du bekommst in derselben Zeile E0026 für r und E0027 für radius. Was ist die beste Lösung?
Punkte: 0 / 3
Weiterlesen
Abschnitt betitelt „Weiterlesen“- E0027 – Rust error codes index (auf Englisch): die offizielle Erklärung dieses Fehlers.
- Mustersyntax – Das Rust-Buch: Structs destrukturieren und verbleibende Teile eines Werts mit
..ignorieren. - Destructuring structs – Rust by Example (auf Englisch): ausführbare Struct-Muster mit
... - Patterns – The Rust Reference (auf Englisch): die genauen Regeln für Struct-Muster und das Rest-Muster.