Zum Inhalt springen

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.)

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);
}

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, etwa kye statt key. 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.

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.

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 }]
▶ Selbst ausprobieren

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: hallo
Farbe: 255 128 0
▶ Selbst ausprobieren

Mö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 }
▶ Selbst ausprobieren

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).

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.

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