Error E0559 de Rust: variant has no field named X (campo de variante)
E0559 significa: estás creando un valor de un enum con Enum::Variante { campo: valor }, y uno de los campos que escribiste no existe en esa variante. Es la versión para enums de E0560, que es el mismo error con structs. Normalmente es un nombre de campo abreviado o mal escrito, un campo que pertenece a otra variante, o llaves en una variante que lleva paréntesis. La solución casi siempre es cambiar una sola palabra. (Esta página forma parte de Errores del compilador de Rust explicados.)
El mensaje de error
Sección titulada «El mensaje de error»error[E0559]: variant `Shape::Circle` has no field named `r` --> src/main.rs:8:33 |8 | let shape = Shape::Circle { r: 2.0 }; // ❌ the field is called `radius` | ^ `Shape::Circle` does not have this field | = note: available fields are: `radius`“Variant Shape::Circle has no field named r” quiere decir “la variante Shape::Circle no tiene ningún campo llamado r”. La etiqueta dice que Shape::Circle no tiene este campo, y la note te enumera los campos disponibles: radius.
Este es el programa que lo produce:
#[derive(Debug)]enum Shape { Circle { radius: f64 }, Rectangle { width: f64, height: f64 },}
fn main() { let shape = Shape::Circle { r: 2.0 }; // ❌ the field is called `radius` println!("{:?}", shape);}Qué significa
Sección titulada «Qué significa»El titular nombra la variante (Shape::Circle) y el campo que escribiste (r). El ^ señala ese campo dentro de las llaves. Rust miró la definición Circle { radius: f64 } y no encontró ningún campo llamado r.
Cada variante de un enum (enumeración) tiene su propia lista de campos. Shape::Circle tiene radius, y Shape::Rectangle tiene width y height. No comparten campos, aunque estén dentro del mismo enum.
Debajo de la flecha, rustc te da una de estas pistas. Léela primero, porque normalmente contiene la respuesta:
note: available fields are: `radius`(los campos disponibles son:radius): no hay ningún nombre parecido. Estos son los campos de esta variante que todavía no has rellenado.help: a field with a similar name exists(existe un campo con un nombre parecido): un error al escribir, comokyeen lugar dekey. rustc te muestra la línea corregida.help: `Message::Write` is a tuple variant, use the appropriate syntax(Message::Writees una variante de tupla, usa la sintaxis adecuada): los campos de la variante no tienen nombre, así que necesita( ), no{ }.note: all struct fields are already assigned(ya se asignaron todos los campos): rellenaste todos los campos reales, y este sobra.
Es como pedir una pizza y decir “masa grande” cuando el menú solo tiene “tamaño de la masa”. En la cocina saben perfectamente lo que quieres, pero el formulario del pedido no tiene ninguna casilla con ese nombre.
Por qué Rust hace esto
Sección titulada «Por qué Rust hace esto»Una variante de enum con campos con nombre, como Circle { radius: f64 }, funciona como un pequeño struct dentro del enum. Cuando creas una, Rust comprueba que le diste exactamente sus campos: ni uno de menos, ni uno de más, ni uno mal escrito. Mira Los enums pueden guardar datos.
Esto importa sobre todo cuando más tarde haces match sobre el enum. El brazo Shape::Circle { radius } => ... solo puede funcionar si cada Circle tiene de verdad un radius. Si Rust dejara pasar Shape::Circle { r: 2.0 }, esa garantía desaparecería. Atrapar el error de escritura al compilar hace que cada Circle de tu programa esté completo.
Cómo solucionarlo
Sección titulada «Cómo solucionarlo»Solución 1: Usa el nombre real del campo de la variante
Sección titulada «Solución 1: Usa el nombre real del campo de la variante»Elige esta cuando rustc te muestre available fields are o a field with a similar name exists. Usa el nombre de la pista. Los nombres de los campos distinguen entre mayúsculas y minúsculas y se escriben en snake_case, así que Radius y radius son nombres distintos.
Un error al escribir recibe la pista de “similar name”:
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' }; |La etiqueta unknown field significa “campo desconocido”, y el help te enseña la línea con key, el nombre correcto.
Un nombre corto como r se parece demasiado poco a radius para que haya sugerencia, así que en su lugar recibes la lista de campos. En los dos casos, escribe el campo que define la variante:
#[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 }, // ✅ el nombre real del campo 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);}Salida:
Circle { radius: 2.0 }Rectangle { width: 3.0, height: 4.0 }[KeyPress { key: 'a' }, Click { x: 10, y: 20 }]Ten cuidado con la forma abreviada de inicialización de campos (field init shorthand). Shape::Circle { r } significa Shape::Circle { r: r }, así que da el mismo E0559. Si tu variable se llama r, escribe el campo completo: Shape::Circle { radius: r }. O cambia el nombre de la variable a radius y escribe Shape::Circle { radius }.
Solución 2: Usa paréntesis para una variante de tupla
Sección titulada «Solución 2: Usa paréntesis para una variante de tupla»Elige esta cuando rustc diga is a tuple variant, use the appropriate syntax. Una variante como Write(String) tiene un campo, pero ese campo no tiene nombre. Así que cualquier nombre que escribas entre llaves está mal:
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 */); |rustc te dice que el campo no existe (field does not exist), te enseña dónde se definió Message::Write y te sugiere la sintaxis con paréntesis. El /* String */ de la sugerencia es un hueco: pon ahí tu valor. Crea una variante de tupla con paréntesis, en el mismo orden que en su definición:
#[derive(Debug)]enum Message { Move { x: i32, y: i32 }, // campos con nombre: usa { } Write(String), // campo sin nombre: usa ( ) Color(u8, u8, u8),}
fn main() { let messages = vec![ Message::Move { x: 1, y: 2 }, Message::Write(String::from("hola")), // ✅ paréntesis Message::Color(255, 128, 0), ]; for m in &messages { match m { Message::Move { x, y } => println!("mover a ({}, {})", x, y), Message::Write(text) => println!("escribir: {}", text), Message::Color(r, g, b) => println!("color: {} {} {}", r, g, b), } }}Salida:
mover a (1, 2)escribir: holacolor: 255 128 0Si prefieres que el campo tenga nombre, cambia la definición a Write { text: String }. Entonces Message::Write { text: ... } funciona. La confusión contraria, paréntesis en una variante con campos con nombre como Shape::Circle(2.0), da otro error: E0533, “expected value, found struct variant” (se esperaba un valor, se encontró una variante de struct).
Solución 3: Elige la variante correcta, o cambia la variante
Sección titulada «Solución 3: Elige la variante correcta, o cambia la variante»Elige esta cuando el campo que escribiste sí existe, pero en otra variante. Aquí radius pertenece a Circle, no a 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`La nota dice que el único campo disponible de Shape::Square es side. Pregúntate cuál de las dos querías. Si querías un círculo, usa Shape::Circle { radius: 2.0 }. Si querías un cuadrado, usa su campo: Shape::Square { side: 2.0 }.
Si ves note: all struct fields are already assigned, la variante está completa y tu campo sobra. Quítalo o, si tu código de verdad lo necesita, añádelo a la definición de la variante:
#[derive(Debug)]enum Shape { Circle { radius: f64 }, Square { side: f64 },}
#[derive(Debug)]enum Message { Move { x: i32, y: i32, z: i32 }, // `z` añadido, porque el código lo necesita}
fn main() { let a = Shape::Circle { radius: 2.0 }; // un círculo tiene un radio let b = Shape::Square { side: 2.0 }; // un cuadrado tiene un lado println!("{:?} y {:?}", a, b);
let m = Message::Move { x: 1, y: 2, z: 3 }; println!("{:?}", m);}Salida:
Circle { radius: 2.0 } y Square { side: 2.0 }Move { x: 1, y: 2, z: 3 }Cuando añades un campo a una variante, todos los sitios que crean esa variante también tienen que rellenarlo. rustc te señalará cada uno con E0063, “missing field” (falta un campo).
Dónde lo verás normalmente
Sección titulada «Dónde lo verás normalmente»Métodos constructores con Self::. Dentro de impl Shape, escribir fn circle(r: f64) -> Shape { Self::Circle { r } } da E0559 para r, por culpa de la forma abreviada. Solución: Self::Circle { radius: r }. Mira Los enums también pueden tener métodos.
Después de renombrar un campo. Cambiaste Circle { r } por Circle { radius } en el enum, y ahora cada Shape::Circle { r: ... } antiguo da E0559 con available fields are: `radius`. Busca el nombre antiguo en todo el proyecto y actualiza cada uso.
En un patrón de match. Escribir un nombre de campo equivocado en un patrón, como Shape::Circle { r } => ..., es el mismo error, pero rustc usa otros códigos: E0026, “variant Shape::Circle does not have a field named r” (la variante Shape::Circle no tiene un campo llamado r), con help: `Shape::Circle` has a field named `radius` (Shape::Circle tiene un campo llamado radius), y además E0027, “pattern does not mention field radius” (el patrón no menciona el campo radius). Solución: Shape::Circle { radius } => ..., o Shape::Circle { radius: r } => ... si quieres mantener el nombre corto. Mira Coincidencia de patrones.
Errores relacionados
Sección titulada «Errores relacionados»- E0560: struct has no field named x: el mismo error en un literal de struct, como
User { nmae: ... }. - E0063: missing field in initializer: lo contrario, un campo que la variante tiene pero que no rellenaste.
- E0599: no method named x found: rustc usa este mismo código cuando el nombre de la variante está mal, como
Shape::Circel { ... }. rustc dice “no variant namedCircelfound for enumShape” (no se encontró ninguna variante llamadaCircelen el enumShape). - E0609: no field on type: un nombre de campo equivocado al leer un campo.
E0026: variant does not have a field named x: el mismo error dentro de un patrón dematch(mira más arriba).E0533: expected value, found struct variant: paréntesis en una variante con campos con nombre, comoShape::Circle(2.0).- Todos los errores del compilador: la lista completa de páginas de errores.
Comprueba lo que aprendiste
Sección titulada «Comprueba lo que aprendiste»Comprueba lo aprendido
1. Para enum Message { Write(String) }, ¿en qué tiene que convertirse Message::Write { text: s }?
2. Tienes let r = 2.0; y escribes Shape::Circle { r }, pero el campo se llama radius. ¿Cómo lo arreglas?
3. Shape::Square { radius: 2.0 } da E0559, y la nota solo enumera side. ¿Qué está pasando?
Puntuación: 0 / 3
Para leer más
Sección titulada «Para leer más»- E0559 — Rust error codes index (en inglés): la explicación oficial de este error.
- Defining an Enum — El libro de Rust (en inglés): variantes con campos con nombre, variantes de tupla y variantes sin datos, con el ejemplo de
Message. También existe una traducción al español de la comunidad del libro. - Enums — Rust by Example (en inglés): ejemplos ejecutables de cada tipo de variante.
- Struct expressions — The Rust Reference (en inglés): las reglas exactas de
Enum::Variante { campo: valor }, incluida la forma abreviada. - E0026 — Rust error codes index (en inglés): la página oficial del mismo error dentro de un patrón.