Rust-Fehler E0026: struct or variant does not have a field named X (Feld im Muster)
E0026 bedeutet: Du nimmst ein Struct oder eine Enum-Variante in einem Muster (Pattern) auseinander, etwa Shape::Circle { r }, und einen der Feldnamen, die du geschrieben hast, gibt es nicht. Es ist die Muster-Version von E0560 und E0559, die denselben Fehler abfangen, wenn du einen Wert erzeugst. Meistens nennt dir rustc den richtigen Namen gleich in einer help:-Zeile, die Lösung ist also oft ein einziges Wort. (Diese Seite gehört zur Reihe Rust-Compilerfehler einfach erklärt.)
Die Fehlermeldung
Abschnitt betitelt „Die Fehlermeldung“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, // ❌ das Feld heißt `radius` | ^ | | | variant `Shape::Circle` does not have this field | help: `Shape::Circle` has a field named `radius`Auf Deutsch: „Die Variante Shape::Circle hat kein Feld namens r.“ Die Markierung sagt „die Variante hat dieses Feld nicht“, und das help schlägt vor: „Shape::Circle hat ein Feld namens radius.“
Dieses Programm erzeugt den Fehler:
enum Shape { Circle { radius: f64 }, Rectangle { width: f64, height: f64 },}
fn area(shape: &Shape) -> f64 { match shape { Shape::Circle { r } => 3.14 * r * r, // ❌ das Feld heißt `radius` Shape::Rectangle { width, height } => width * height, }}
fn main() { println!("{}", area(&Shape::Circle { radius: 1.0 }));}Für dieselbe Zeile siehst du noch einen zweiten Fehler: E0027, „pattern does not mention field radius“ (das Muster erwähnt das Feld radius nicht). Das ist derselbe Fehler, nur von der anderen Seite betrachtet. Rust hat ein Feld gefunden, das du genannt hast, das es aber nicht gibt (r), und ein echtes Feld, das du nicht genannt hast (radius). Korrigier den Namen, und beide Fehler verschwinden.
Was sie bedeutet
Abschnitt betitelt „Was sie bedeutet“Die Überschrift nennt das Struct oder die Variante, auf die du prüfst (Shape::Circle), und das Feld, das du geschrieben hast (r). Das ^ zeigt auf diesen Namen in den geschweiften Klammern des Musters.
In einem Muster sind die Namen in { } Feldnamen, keine neuen Variablennamen, die du dir aussuchen darfst. Shape::Circle { r } ist die Kurzform von Shape::Circle { r: r }: „Nimm das Feld namens r und leg es in eine Variable namens r.“ Circle hat kein Feld namens r, also hört Rust hier auf.
Unter dem Pfeil gibt dir rustc einen dieser Hinweise:
help: `Shape::Circle` has a field named `radius`: Es gibt genau ein Feld, das du nicht erwähnt hast, also vermutet rustc, dass du das meinst.help: a field with a similar name exists(es gibt ein Feld mit ähnlichem Namen): ein Tippfehler, etwanmaestattname. rustc zeigt die korrigierte Zeile.- Gar kein Hinweis: rustc konnte nicht raten. Schau in die Definition des Structs oder Enums, dort stehen die echten Namen.
Das ist, als würdest du in der Bibliothek nach „dem Buch im Regal Irgendwie-Romane“ fragen. Die Bibliothekarin weiß, dass du irgendein Regal meinst, aber sie kann dich nur zu Regalen bringen, die es wirklich gibt.
Warum Rust das macht
Abschnitt betitelt „Warum Rust das macht“Ein Muster wie Shape::Circle { radius } ist ein Versprechen: „Wenn der Wert ein Circle ist, gib mir seinen radius.“ Rust prüft dieses Versprechen beim Kompilieren gegen die Definition. So kann ein Muster nie nach Daten fragen, die gar nicht da sind. Siehe Tupel und Structs destrukturieren.
In Sprachen ohne diese Prüfung bekommst du beim Lesen eines fehlenden Schlüssels undefined oder null, und der Fehler zeigt sich erst viel später, weit weg vom Tippfehler. In Rust kommt der Tippfehler nicht am Compiler vorbei. Das schützt dich auch, wenn jemand ein Feld umbenennt: Jedes Muster, das noch den alten Namen benutzt, meldet E0026. So wird keins davon stillschweigend vergessen.
So behebst du den Fehler
Abschnitt betitelt „So behebst du den Fehler“Lösung 1: Den echten Feldnamen benutzen
Abschnitt betitelt „Lösung 1: Den echten Feldnamen benutzen“Nimm diese Lösung in den meisten Fällen. Benutze den Namen aus der help:-Zeile, oder schau in die Definition. Feldnamen unterscheiden Groß- und Kleinschreibung und werden in snake_case geschrieben.
Bei einem Tippfehler bekommst du den Hinweis „similar name“ und die korrigierte Zeile:
error[E0026]: struct `User` does not have a field named `nmae` --> src/main.rs:8:16 |8 | let User { nmae, age } = user; // ❌ Tippfehler: das Feld heißt `name` | ^^^^ struct `User` does not have this field |help: a field with a similar name exists |8 - let User { nmae, age } = user; // ❌ Tippfehler: das Feld heißt `name`8 + let User { name, age } = user; // ❌ Tippfehler: das Feld heißt `name` |Das Programm dazu:
struct User { name: String, age: u32,}
fn main() { let user = User { name: String::from("Ferris"), age: 7 }; let User { nmae, age } = user; // ❌ Tippfehler: das Feld heißt `name` println!("{} ist {} Jahre alt", nmae, age);}Schreib die Feldnamen genau so wie in der Definition. Dann funktioniert die Kurzform, und du bekommst Variablen mit denselben Namen:
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, // ✅ der echte Feldname 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!("Fläche: {:.2}", area(shape)); }
let user = User { name: String::from("Ferris"), age: 7 }; let User { name, age } = user; // ✅ `name`, nicht `nmae` println!("{} ist {} Jahre alt", name, age);}Ausgabe:
Fläche: 12.56Fläche: 12.00Ferris ist 7 Jahre altLösung 2: Mit feld: name deinen eigenen Variablennamen behalten
Abschnitt betitelt „Lösung 2: Mit feld: name deinen eigenen Variablennamen behalten“Nimm diese Lösung, wenn dir der kurze Name r gefällt und die Variable einfach so heißen soll. Schreib den echten Feldnamen, einen Doppelpunkt und dann deinen Variablennamen: Shape::Circle { radius: r }. Lies das als „Nimm das Feld radius und nenn es 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, // ✅ Feld `radius`, Variable `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!("klein: {:.2}", area(&small)); println!("breit: {:.2}", area(&wide));}Ausgabe:
klein: 3.14breit: 25.00Das ist auch praktisch, wenn zwei Felder sonst mit Variablen kollidieren würden, die du schon hast, oder wenn der Feldname lang ist.
Lösung 3: Prüfen, ob du die richtige Variante abfragst
Abschnitt betitelt „Lösung 3: Prüfen, ob du die richtige Variante abfragst“Nimm diese Lösung, wenn es das Feld, das du geschrieben hast, wirklich gibt, nur in einer anderen Variante. Jede Variante eines Enums hat ihre eigenen Felder. Hier gehört x zu Click, aber der Zweig prüft auf KeyPress:
error[E0026]: variant `Event::KeyPress` does not have a field named `x` --> src/main.rs:9:27 |9 | Event::KeyPress { x, .. } => format!("Taste bei {}", x), // ❌ `x` gehört zu `Click` | ^ | | | variant `Event::KeyPress` does not have this field | help: `Event::KeyPress` has a field named `key`Das Programm dazu:
enum Event { Click { x: i32, y: i32 }, KeyPress { key: char },}
fn describe(event: &Event) -> String { match event { Event::Click { x, y } => format!("Klick bei ({}, {})", x, y), Event::KeyPress { x, .. } => format!("Taste bei {}", x), // ❌ `x` gehört zu `Click` }}
fn main() { println!("{}", describe(&Event::KeyPress { key: 'a' }));}Der Vorschlag von rustc (key) bedeutet nur „das einzige Feld, das du nicht erwähnt hast“. Übernimm ihn also nicht blind. Frag dich, was dieser Zweig tun soll. Ein Tastendruck hat keine Position, also ist die richtige Lösung hier, das Feld zu benutzen, das KeyPress wirklich hat:
enum Event { Click { x: i32, y: i32 }, KeyPress { key: char },}
fn describe(event: &Event) -> String { match event { Event::Click { x, y } => format!("Klick bei ({}, {})", x, y), Event::KeyPress { key } => format!("Taste '{}' gedrückt", key), // ✅ KeyPress hat `key` }}
fn main() { let events = [Event::Click { x: 10, y: 20 }, Event::KeyPress { key: 'a' }]; for event in &events { println!("{}", describe(event)); }}Ausgabe:
Klick bei (10, 20)Taste 'a' gedrücktSoll ein Tastendruck wirklich eine Position haben, ergänze die Felder stattdessen in der Variante: KeyPress { key: char, x: i32, y: i32 }. Dann muss aber auch jede Stelle, die ein KeyPress erzeugt, sie ausfüllen (rustc zeigt mit E0063 auf jede davon).
Wo du ihn oft siehst
Abschnitt betitelt „Wo du ihn oft siehst“Nach dem Umbenennen eines Felds. Du hast r im Enum in radius umbenannt, und jetzt meldet jeder Zweig Shape::Circle { r } => ... den Fehler E0026. Such im Projekt nach dem alten Namen und pass jedes Muster an, oder benutz radius: r, um den alten Variablennamen zu behalten.
In if let und let. if let Some(User { nmae, .. }) = find_user() ergibt denselben Fehler. Ein .. hilft hier nicht: .. überspringt Felder, die du nicht nennst, aber jeder Name, den du schreibst, muss trotzdem existieren. Lösung: User { name, .. }.
Geschweifte Klammern bei einer Tupel-Variante oder einem Tupel-Struct. Für struct Point(i32, i32); hat das Muster Point { x, y } keine echten Feldnamen, auf die es passen könnte. rustc meldet das mit einem anderen Code, E0769, „tuple variant Point written as struct variant“ (Tupel-Variante Point als Struct-Variante geschrieben), und schlägt Point(x, y) vor. Siehe Enums mit Daten destrukturieren.
Verwandte Fehler
Abschnitt betitelt „Verwandte Fehler“- E0027: pattern does not mention field: der Zwilling von E0026, ein echtes Feld, das dein Muster weggelassen hat. Erscheint oft zusammen mit E0026.
- E0559: variant has no field named x: derselbe falsche Name beim Erzeugen einer Enum-Variante.
- E0560: struct has no field named x: derselbe falsche Name beim Erzeugen eines Structs.
- E0609: no field on type: derselbe falsche Name beim Lesen eines Felds, etwa
user.nmae. - E0533: expected unit struct, unit variant or constant: Die Variante stimmt, aber das Muster hat die falsche Form (keine
{ }). - Alle Compilerfehler einfach erklärt
Kurzer Check
Abschnitt betitelt „Kurzer Check“Kurzer Check
1. Wonach fragt das Muster Shape::Circle { r } bei enum Shape { Circle { radius: f64 } }?
2. Du willst das Feld radius in einer Variable namens r haben. Welches Muster funktioniert?
3. Kompiliert User { nmae, .. }, wenn das Feld name heißt?
Punkte: 0 / 3
Weiterlesen
Abschnitt betitelt „Weiterlesen“- E0026 – Rust error codes index (auf Englisch): die offizielle Erklärung dieses Fehlers.
- Mustersyntax – Das Rust-Buch: Structs und Enums destrukturieren, einschließlich
feld: variableund... - Destructuring structs – Rust by Example (auf Englisch): kleine, ausführbare Beispiele für Struct-Muster.
- Patterns – The Rust Reference (auf Englisch): die genauen Regeln für Struct-Muster und die Kurzform für Felder.