Error E0026 de Rust: struct or variant does not have a field named X (campo en un patrón)
E0026 significa: estás desarmando un struct o una variante de enum con un patrón, como Shape::Circle { r }, y uno de los nombres de campo que escribiste no existe. Es la versión para patrones de E0560 y E0559, que detectan el mismo error cuando creas un valor. Normalmente rustc te dice el nombre correcto en una línea help:, así que la solución suele ser 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[E0026]: variant `Shape::Circle` does not have a field named `r` --> src/main.rs:8:25 |8 | Shape::Circle { r } => 3.14 * r * r, // ❌ the field is called `radius` | ^ | | | variant `Shape::Circle` does not have this field | help: `Shape::Circle` has a field named `radius`“Variant Shape::Circle does not have a field named r” quiere decir “la variante Shape::Circle no tiene ningún campo llamado r”. La etiqueta repite que la variante no tiene este campo, y el help te dice que Shape::Circle sí tiene un campo llamado radius.
Este es el programa que lo produce:
enum Shape { Circle { radius: f64 }, Rectangle { width: f64, height: f64 },}
fn area(shape: &Shape) -> f64 { match shape { Shape::Circle { r } => 3.14 * r * r, // ❌ the field is called `radius` Shape::Rectangle { width, height } => width * height, }}
fn main() { println!("{}", area(&Shape::Circle { radius: 1.0 }));}En la misma línea también verás un segundo error: E0027, “pattern does not mention field radius” (el patrón no menciona el campo radius). Es el mismo error visto desde el otro lado. Rust encontró un campo que nombraste y que no existe (r), y un campo real que no nombraste (radius). Corrige el nombre y desaparecen los dos.
Qué significa
Sección titulada «Qué significa»El titular nombra el struct o la variante que estás comparando (Shape::Circle) y el campo que escribiste (r). El ^ señala ese nombre dentro de las llaves del patrón.
En un patrón, los nombres dentro de { } son nombres de campos, no nombres nuevos de variables que puedas elegir a tu gusto. Shape::Circle { r } es la forma corta de Shape::Circle { r: r }: “toma el campo llamado r y guárdalo en una variable llamada r”. Circle no tiene ningún campo llamado r, así que Rust se detiene.
Debajo de la flecha, rustc te da una de estas pistas:
help: `Shape::Circle` has a field named `radius`(Shape::Circletiene un campo llamadoradius): queda exactamente un campo que no mencionaste, así que rustc supone que te referías a ese.help: a field with a similar name exists(existe un campo con un nombre parecido): un error al escribir, comonmaeen lugar dename. rustc te muestra la línea corregida.- Ninguna pista: rustc no pudo adivinarlo. Mira la definición del struct o del enum para ver los nombres reales.
Es como pedirle a una bibliotecaria “el libro de la estantería que se llama Más o menos ficción”. Ella sabe que quieres alguna estantería, pero solo puede llevarte a las que existen de verdad.
Por qué Rust hace esto
Sección titulada «Por qué Rust hace esto»Un patrón como Shape::Circle { radius } es una promesa: “cuando el valor sea un Circle, dame su radius”. Rust comprueba esa promesa contra la definición al compilar, así que un patrón nunca puede pedir datos que no están ahí. Mira Desestructurar tuplas y structs.
En los lenguajes que no hacen esta comprobación, leer una clave que no existe te da undefined o null, y el bug aparece mucho más tarde, lejos del error al escribir. En Rust, el error al escribir no pasa del compilador. También te protege cuando alguien cambia el nombre de un campo: cada patrón que todavía usa el nombre antiguo se ilumina con E0026, así que no se te olvida ninguno sin darte cuenta.
Cómo solucionarlo
Sección titulada «Cómo solucionarlo»Solución 1: Usa el nombre real del campo
Sección titulada «Solución 1: Usa el nombre real del campo»Elige esta la mayoría de las veces. Usa el nombre de la línea help:, o mira la definición. Los nombres de los campos distinguen entre mayúsculas y minúsculas y se escriben en snake_case.
Un error al escribir recibe la pista de “similar name” y la línea corregida:
error[E0026]: struct `User` does not have a field named `nmae` --> src/main.rs:8:16 |8 | let User { nmae, age } = user; // ❌ typo: the field is `name` | ^^^^ struct `User` does not have this field |help: a field with a similar name exists |8 - let User { nmae, age } = user; // ❌ typo: the field is `name`8 + let User { name, age } = user; // ❌ typo: the field is `name` |La etiqueta dice que el struct User no tiene este campo, y el help te enseña la misma línea con name, el nombre correcto.
El programa que hay detrás:
struct User { name: String, age: u32,}
fn main() { let user = User { name: String::from("Ferris"), age: 7 }; let User { nmae, age } = user; // ❌ typo: the field is `name` println!("{} is {} years old", nmae, age);}Escribe los nombres de los campos exactamente como en la definición. Así la forma corta funciona, y obtienes variables con los mismos nombres:
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, // ✅ el nombre real del campo 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!("área: {:.2}", area(shape)); }
let user = User { name: String::from("Ferris"), age: 7 }; let User { name, age } = user; // ✅ `name`, no `nmae` println!("{} tiene {} años", name, age);}Salida:
área: 12.56área: 12.00Ferris tiene 7 añosSolución 2: Ponle tu propio nombre a la variable con campo: nombre
Sección titulada «Solución 2: Ponle tu propio nombre a la variable con campo: nombre»Elige esta cuando te gusta el nombre corto r y solo quieres que la variable se llame así. Escribe el nombre real del campo, dos puntos y luego el nombre de tu variable: Shape::Circle { radius: r }. Léelo como “toma el campo radius y llámalo 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, // ✅ campo `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!("pequeño: {:.2}", area(&small)); println!("ancho: {:.2}", area(&wide));}Salida:
pequeño: 3.14ancho: 25.00También es útil cuando dos campos chocarían con variables que ya tienes, o cuando el nombre del campo es largo.
Solución 3: Comprueba que estás comparando la variante correcta
Sección titulada «Solución 3: Comprueba que estás comparando la variante correcta»Elige esta cuando el campo que escribiste existe, pero en otra variante. Cada variante de un enum tiene sus propios campos. Aquí x pertenece a Click, pero el brazo compara con KeyPress:
error[E0026]: variant `Event::KeyPress` does not have a field named `x` --> src/main.rs:9:27 |9 | Event::KeyPress { x, .. } => format!("key at {}", x), // ❌ `x` belongs to `Click` | ^ | | | variant `Event::KeyPress` does not have this field | help: `Event::KeyPress` has a field named `key`La variante Event::KeyPress no tiene un campo x, y el help te dice que tiene uno llamado key.
El programa que hay detrás:
enum Event { Click { x: i32, y: i32 }, KeyPress { key: char },}
fn describe(event: &Event) -> String { match event { Event::Click { x, y } => format!("click at ({}, {})", x, y), Event::KeyPress { x, .. } => format!("key at {}", x), // ❌ `x` belongs to `Click` }}
fn main() { println!("{}", describe(&Event::KeyPress { key: 'a' }));}La sugerencia de rustc (key) solo significa “el único campo que no mencionaste”, así que no la sigas a ciegas. Pregúntate qué debería hacer este brazo. Una tecla pulsada no tiene posición, así que aquí la solución correcta es usar el campo que KeyPress tiene de verdad:
enum Event { Click { x: i32, y: i32 }, KeyPress { key: char },}
fn describe(event: &Event) -> String { match event { Event::Click { x, y } => format!("clic en ({}, {})", x, y), Event::KeyPress { key } => format!("tecla '{}' pulsada", key), // ✅ KeyPress tiene `key` }}
fn main() { let events = [Event::Click { x: 10, y: 20 }, Event::KeyPress { key: 'a' }]; for event in &events { println!("{}", describe(event)); }}Salida:
clic en (10, 20)tecla 'a' pulsadaSi una tecla pulsada de verdad debería tener posición, añade los campos a la variante: KeyPress { key: char, x: i32, y: i32 }. Entonces cada sitio que crea un KeyPress también tiene que rellenarlos (rustc te señala cada uno con E0063).
Dónde lo verás normalmente
Sección titulada «Dónde lo verás normalmente»Después de cambiar el nombre de un campo. Cambiaste r por radius en el enum, y ahora cada brazo Shape::Circle { r } => ... da E0026. Busca el nombre antiguo en el proyecto y actualiza cada patrón, o usa radius: r para conservar el nombre antiguo de la variable.
En if let y let. if let Some(User { nmae, .. }) = find_user() da el mismo error. Añadir .. no ayuda aquí: .. se salta los campos que no nombras, pero cada nombre que sí escribes tiene que existir. Solución: User { name, .. }.
Llaves en una variante de tupla o un tuple struct. Para struct Point(i32, i32);, el patrón Point { x, y } no tiene nombres de campos reales con los que coincidir. rustc lo informa con otro código, E0769, “tuple variant Point written as struct variant” (variante de tupla Point escrita como variante de struct), y sugiere Point(x, y). Mira Desestructurar enums con datos.
Errores relacionados
Sección titulada «Errores relacionados»- E0027: pattern does not mention field: el gemelo de E0026, un campo real que tu patrón dejó fuera. A menudo aparecen juntos.
- E0559: variant has no field named x: el mismo nombre equivocado al crear una variante de enum.
- E0560: struct has no field named x: el mismo nombre equivocado al crear un struct.
- E0609: no field on type: el mismo nombre equivocado al leer un campo, como
user.nmae. - E0533: expected unit struct, unit variant or constant: la variante es correcta, pero el patrón tiene la forma equivocada (sin
{ }). - 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. Con enum Shape { Circle { radius: f64 } }, ¿qué pide el patrón Shape::Circle { r }?
2. Quieres el campo radius en una variable llamada r. ¿Qué patrón funciona?
3. ¿Compila User { nmae, .. } si el campo se llama name?
Puntuación: 0 / 3
Para leer más
Sección titulada «Para leer más»- E0026 — Rust error codes index (en inglés): la explicación oficial de este error.
- Pattern Syntax — El libro de Rust (en inglés): desestructurar structs y enums, incluidos
campo: variabley... También existe una traducción al español de la comunidad del libro. - Destructuring structs — Rust by Example (en inglés): ejemplos cortos y ejecutables de patrones de structs.
- Patterns — The Rust Reference (en inglés): las reglas exactas de los patrones de structs y de la forma abreviada de los campos.