Rust-Fehler E0559: variant has no field named X (Feld der Enum-Variante)
E0559 bedeutet: Du erzeugst einen Enum-Wert mit Enum::Variant { field: value }, und eines der Felder, die du geschrieben hast, gibt es in dieser Variante nicht. Es ist die Enum-Version von E0560, demselben Fehler bei Structs. Meistens ist der Feldname zu kurz oder falsch geschrieben, das Feld gehört zu einer anderen Variante, oder du hast geschweifte Klammern bei einer Variante benutzt, die runde Klammern braucht. Die Lösung ist fast immer ein einziges Wort. (Diese Seite gehört zur Reihe Rust-Compilerfehler einfach erklärt.)
Die Fehlermeldung
Abschnitt betitelt „Die Fehlermeldung“error[E0559]: variant `Shape::Circle` has no field named `r` --> src/main.rs:8:33 |8 | let shape = Shape::Circle { r: 2.0 }; // ❌ das Feld heißt `radius` | ^ `Shape::Circle` does not have this field | = note: available fields are: `radius`Auf Deutsch: „Die Variante Shape::Circle hat kein Feld namens r.“ Die Markierung sagt „Shape::Circle hat dieses Feld nicht“, und die note nennt die verfügbaren Felder: radius.
Dieses Programm erzeugt den Fehler:
#[derive(Debug)]enum Shape { Circle { radius: f64 }, Rectangle { width: f64, height: f64 },}
fn main() { let shape = Shape::Circle { r: 2.0 }; // ❌ das Feld heißt `radius` println!("{:?}", shape);}Was sie bedeutet
Abschnitt betitelt „Was sie bedeutet“Die Überschrift nennt die Variante (Shape::Circle) und das Feld, das du geschrieben hast (r). Das ^ zeigt auf dieses Feld in den geschweiften Klammern. Rust hat sich die Definition Circle { radius: f64 } angesehen und kein Feld namens r gefunden.
Jede Variante eines Enums hat ihre eigene Feldliste. Shape::Circle hat radius, Shape::Rectangle hat width und height. Sie teilen sich keine Felder, auch nicht innerhalb desselben Enums.
Unter dem Pfeil gibt dir rustc einen dieser Hinweise. Lies ihn zuerst, meistens steht die Antwort schon drin:
note: available fields are: `radius`(verfügbare Felder sind …): kein ähnlicher Name. Das sind die Felder dieser Variante, die du noch nicht ausgefüllt hast.help: a field with a similar name exists(es gibt ein Feld mit ähnlichem Namen): ein Tippfehler, etwakyestattkey. rustc zeigt die korrigierte Zeile.help: `Message::Write` is a tuple variant, use the appropriate syntax(das ist eine Tupel-Variante, benutze die passende Syntax): Die Felder der Variante haben keine Namen. Sie braucht also( ), nicht{ }.note: all struct fields are already assigned(alle Felder sind schon zugewiesen): Du hast jedes echte Feld ausgefüllt, und dieses ist zu viel.
Das ist, als würdest du eine Pizza bestellen und „großer Rand“ ankreuzen wollen, obwohl auf dem Bestellzettel nur „Randgröße“ steht. Die Küche weiß genau, was du meinst. Aber auf dem Zettel gibt es kein Kästchen mit diesem Namen.
Warum Rust das macht
Abschnitt betitelt „Warum Rust das macht“Eine Enum-Variante mit benannten Feldern wie Circle { radius: f64 } funktioniert wie ein kleines Struct im Enum. Erzeugst du eine, prüft Rust, dass du genau ihre Felder angegeben hast: keins fehlt, keins zu viel, keins falsch geschrieben. Siehe Enums können Daten enthalten.
Das ist vor allem wichtig, wenn du später mit match auf das Enum prüfst. Der Zweig Shape::Circle { radius } => ... funktioniert nur, wenn wirklich jeder Circle einen radius hat. Würde Rust Shape::Circle { r: 2.0 } durchlassen, wäre diese Garantie weg. Weil der Tippfehler schon beim Kompilieren auffällt, ist jeder Circle in deinem Programm vollständig.
So behebst du den Fehler
Abschnitt betitelt „So behebst du den Fehler“Lösung 1: Den echten Feldnamen der Variante benutzen
Abschnitt betitelt „Lösung 1: Den echten Feldnamen der Variante benutzen“Nimm diese Lösung, wenn rustc available fields are oder a field with a similar name exists zeigt. Nimm den Namen aus dem Hinweis. Feldnamen unterscheiden Groß- und Kleinschreibung und werden in snake_case geschrieben. Radius und radius sind also verschiedene Namen.
Bei einem Tippfehler bekommst du den Hinweis auf einen „ähnlichen Namen“:
error[E0559]: variant `Event::KeyPress` has no field named `kye` --> src/main.rs:8:31 |8 | let e = Event::KeyPress { kye: 'a' }; | ^^^ unknown field |help: a field with a similar name exists |8 - let e = Event::KeyPress { kye: 'a' };8 + let e = Event::KeyPress { key: 'a' }; |Ein kurzer Name wie r ist zu weit von radius entfernt für einen Vorschlag. Dann bekommst du stattdessen die Liste der Felder. So oder so: Schreib das Feld, das die Variante definiert:
#[derive(Debug)]enum Shape { Circle { radius: f64 }, Rectangle { width: f64, height: f64 },}
#[derive(Debug)]enum Event { Click { x: i32, y: i32 }, KeyPress { key: char },}
fn main() { let shapes = [ Shape::Circle { radius: 2.0 }, // ✅ der echte Feldname Shape::Rectangle { width: 3.0, height: 4.0 }, ]; for shape in &shapes { println!("{:?}", shape); }
let events = [Event::KeyPress { key: 'a' }, Event::Click { x: 10, y: 20 }]; println!("{:?}", events);}Ausgabe:
Circle { radius: 2.0 }Rectangle { width: 3.0, height: 4.0 }[KeyPress { key: 'a' }, Click { x: 10, y: 20 }]Pass bei der Kurzschreibweise für Feldinitialisierung (Field Init Shorthand) auf. Shape::Circle { r } bedeutet Shape::Circle { r: r } und ergibt deshalb ebenfalls E0559. Heißt deine Variable r, schreib das Feld aus: Shape::Circle { radius: r }. Oder benenn die Variable in radius um und schreib Shape::Circle { radius }.
Lösung 2: Bei einer Tupel-Variante runde Klammern benutzen
Abschnitt betitelt „Lösung 2: Bei einer Tupel-Variante runde Klammern benutzen“Nimm diese Lösung, wenn rustc is a tuple variant, use the appropriate syntax sagt. Eine Variante wie Write(String) hat zwar ein Feld, aber dieses Feld hat keinen Namen. Jeder Name, den du in geschweifte Klammern schreibst, ist also falsch:
error[E0559]: variant `Message::Write` has no field named `text` --> src/main.rs:8:30 |4 | Write(String), | ----- `Message::Write` defined here...8 | let m = Message::Write { text: String::from("hi") }; | ^^^^ field does not exist |help: `Message::Write` is a tuple variant, use the appropriate syntax |8 - let m = Message::Write { text: String::from("hi") };8 + let m = Message::Write(/* String */); |Die Markierung sagt „das Feld gibt es nicht“. Das /* String */ im Vorschlag ist ein Platzhalter: Dort kommt dein Wert hin. Erzeuge eine Tupel-Variante mit runden Klammern, in derselben Reihenfolge wie in ihrer Definition:
#[derive(Debug)]enum Message { Move { x: i32, y: i32 }, // benannte Felder: { } benutzen Write(String), // unbenanntes Feld: ( ) benutzen Color(u8, u8, u8),}
fn main() { let messages = vec![ Message::Move { x: 1, y: 2 }, Message::Write(String::from("hallo")), // ✅ runde Klammern Message::Color(255, 128, 0), ]; for m in &messages { match m { Message::Move { x, y } => println!("bewegen nach ({}, {})", x, y), Message::Write(text) => println!("schreiben: {}", text), Message::Color(r, g, b) => println!("Farbe: {} {} {}", r, g, b), } }}Ausgabe:
bewegen nach (1, 2)schreiben: halloFarbe: 255 128 0Möchtest du dem Feld lieber einen Namen geben, ändere die Definition zu Write { text: String }. Dann funktioniert Message::Write { text: ... }. Die umgekehrte Verwechslung – runde Klammern bei einer Variante mit benannten Feldern, etwa Shape::Circle(2.0) – ergibt einen anderen Fehler: E0533, „expected value, found struct variant“ (Wert erwartet, Struct-Variante gefunden).
Lösung 3: Die richtige Variante wählen oder die Variante ändern
Abschnitt betitelt „Lösung 3: Die richtige Variante wählen oder die Variante ändern“Nimm diese Lösung, wenn es das Feld, das du geschrieben hast, zwar gibt – nur in einer anderen Variante. Hier gehört radius zu Circle, nicht zu Square:
error[E0559]: variant `Shape::Square` has no field named `radius` --> src/main.rs:8:29 |8 | let s = Shape::Square { radius: 2.0 }; | ^^^^^^ `Shape::Square` does not have this field | = note: available fields are: `side`Frag dich, welche du gemeint hast. Wolltest du einen Kreis, benutze Shape::Circle { radius: 2.0 }. Wolltest du ein Quadrat, benutze sein Feld: Shape::Square { side: 2.0 }.
Siehst du note: all struct fields are already assigned, ist die Variante vollständig, und dein Feld ist zu viel. Entferne es. Oder füge es zur Definition der Variante hinzu, wenn dein Code es wirklich braucht:
#[derive(Debug)]enum Shape { Circle { radius: f64 }, Square { side: f64 },}
#[derive(Debug)]enum Message { Move { x: i32, y: i32, z: i32 }, // `z` hinzugefügt, weil der Code es braucht}
fn main() { let a = Shape::Circle { radius: 2.0 }; // ein Kreis hat einen Radius let b = Shape::Square { side: 2.0 }; // ein Quadrat hat eine Seite println!("{:?} und {:?}", a, b);
let m = Message::Move { x: 1, y: 2, z: 3 }; println!("{:?}", m);}Ausgabe:
Circle { radius: 2.0 } und Square { side: 2.0 }Move { x: 1, y: 2, z: 3 }Fügst du einer Variante ein Feld hinzu, muss jede Stelle, die diese Variante erzeugt, das Feld ebenfalls ausfüllen. rustc zeigt dir jede davon mit E0063, „missing field“ (fehlendes Feld).
Wo du ihn oft siehst
Abschnitt betitelt „Wo du ihn oft siehst“Konstruktor-Methoden mit Self::. Schreibst du in impl Shape die Funktion fn circle(r: f64) -> Shape { Self::Circle { r } }, bekommst du wegen der Kurzschreibweise E0559 für r. Lösung: Self::Circle { radius: r }. Siehe Auch Enums können Methoden haben.
Nachdem du ein Feld umbenannt hast. Du hast im Enum Circle { r } in Circle { radius } umbenannt, und jedes alte Shape::Circle { r: ... } ergibt jetzt E0559 mit available fields are: `radius`. Such im Projekt nach dem alten Namen und ändere jede Stelle.
In einem match-Pattern. Schreibst du den falschen Feldnamen in ein Pattern, etwa Shape::Circle { r } => ..., ist das derselbe Fehler, aber rustc benutzt andere Codes: E0026, „variant Shape::Circle does not have a field named r“ (die Variante hat kein Feld namens r), mit help: `Shape::Circle` has a field named `radius`, dazu E0027 „pattern does not mention field radius“ (das Pattern erwähnt das Feld radius nicht). Lösung: Shape::Circle { radius } => ..., oder Shape::Circle { radius: r } => ..., wenn du den kurzen Namen behalten willst. Siehe Pattern Matching.
Verwandte Fehler
Abschnitt betitelt „Verwandte Fehler“- E0560: struct has no field named x: derselbe Fehler bei einem Struct-Literal, etwa
User { nmae: ... }. - E0063: missing field in initializer: das Gegenteil – ein Feld, das die Variante hat, das du aber nicht ausgefüllt hast.
- E0599: no method named x found: Diesen Code benutzt rustc, wenn der Name der Variante falsch ist, etwa
Shape::Circel { ... }. rustc sagt dann „no variant namedCircelfound for enumShape“ (keine Variante namensCircelim EnumShape). - E0609: no field on type: ein falscher Feldname beim Lesen eines Felds.
E0026: variant does not have a field named x: derselbe Fehler in einemmatch-Pattern (siehe oben).E0533: expected value, found struct variant: runde Klammern bei einer Variante mit benannten Feldern, etwaShape::Circle(2.0).- Alle Compilerfehler einfach erklärt
Kurzer Check
Abschnitt betitelt „Kurzer Check“Kurzer Check
1. Was muss bei enum Message { Write(String) } aus Message::Write { text: s } werden?
2. Du hast let r = 2.0; und schreibst Shape::Circle { r }, aber das Feld heißt radius. Wie behebst du das?
3. Shape::Square { radius: 2.0 } ergibt E0559, und die Notiz nennt nur side. Was ist los?
Punkte: 0 / 3
Weiterlesen
Abschnitt betitelt „Weiterlesen“- E0559 – Rust error codes index (auf Englisch): die offizielle Erklärung dieses Fehlers.
- Eine Aufzählung definieren – Das Rust-Buch: Varianten mit benannten Feldern, Tupel-Varianten und Varianten ohne Daten, mit dem Beispiel
Message. - Enums – Rust by Example (auf Englisch): ausführbare Beispiele für jede Art von Variante.
- Struct expressions – The Rust Reference (auf Englisch): die genauen Regeln für
Enum::Variant { field: value }, auch für die Kurzschreibweise. - E0026 – Rust error codes index (auf Englisch): die offizielle Seite zum selben Fehler in einem Pattern.