Error E0027 de Rust: pattern does not mention field X (faltan campos en el patrón)
E0027 significa: estás desarmando un struct o una variante de enum con un patrón, como let Order { item, quantity } = order;, y no mencionaste todos los campos. En Rust, un patrón de struct tiene que tener en cuenta todos los campos, o nombrándolos o diciendo “y el resto” con ... Es uno de los errores más amables que hay: rustc te escribe la solución exacta, y casi siempre son dos puntos. (Esta página forma parte de Errores del compilador de Rust explicados.)
El mensaje de error
Sección titulada «El mensaje de error»error[E0027]: pattern does not mention fields `id`, `paid` --> src/main.rs:10:9 |10 | let Order { item, quantity } = order; // ❌ `id` and `paid` are not mentioned | ^^^^^^^^^^^^^^^^^^^^^^^^ missing fields `id`, `paid` |help: include the missing fields in the pattern |10 | let Order { item, quantity, id, paid } = order; // ❌ `id` and `paid` are not mentioned | ++++++++++help: if you don't care about these missing fields, you can explicitly ignore them |10 | let Order { item, quantity, id: _, paid: _ } = order; // ❌ `id` and `paid` are not mentioned | ++++++++++++++++help: or always ignore missing fields here |10 | let Order { item, quantity, .. } = order; // ❌ `id` and `paid` are not mentioned | ++++“Pattern does not mention fields id, paid” quiere decir “el patrón no menciona los campos id y paid”. La etiqueta missing fields significa “faltan campos”, y debajo vienen tres sugerencias que te explicamos enseguida.
Este es el programa que lo produce:
struct Order { id: u32, item: String, quantity: u32, paid: bool,}
fn main() { let order = Order { id: 1, item: String::from("keyboard"), quantity: 2, paid: true }; let Order { item, quantity } = order; // ❌ `id` and `paid` are not mentioned println!("{} x {}", quantity, item);}Qué significa
Sección titulada «Qué significa»El titular enumera los campos que tu patrón dejó fuera (id y paid). El ^^^ subraya el patrón entero, porque el problema no es una palabra equivocada, sino algo que falta.
Luego rustc te da tres sugerencias help:. Todas son válidas, y significan cosas distintas:
include the missing fields(incluye los campos que faltan): nómbralos, y así también obtienes las variablesidypaid.explicitly ignore them(ignóralos de forma explícita): escribeid: _, paid: _. No obtienes variables, pero has nombrado todos los campos.always ignore missing fields here(ignora siempre aquí los campos que falten): escribe... Significa “y cualquier otro campo, no me importan”.
Es como una lista de control en la entrada que dice “marca todas las casillas, o marca Otros: omitir”. No puedes dejar casillas en blanco sin más.
Por qué Rust hace esto
Sección titulada «Por qué Rust hace esto»En Rust, un patrón de struct tiene que estar completo salvo que digas lo contrario. Así tu intención queda clara para quien lea el código después. Order { item, quantity, .. } dice “solo necesito estos dos”. Order { id, item, quantity, paid } dice “he pensado en todos los campos”. Mira Ignorar partes con _ y ...
La verdadera ventaja llega cuando el struct cambia. Si alguien añade un campo discount a Order, un patrón que nombra todos los campos se rompe con E0027, y eso te señala código que quizá tenga que tratar el campo nuevo. Un patrón con .. sigue compilando. Rust te deja elegir qué comportamiento quieres, pero no lo adivina por ti.
Cómo solucionarlo
Sección titulada «Cómo solucionarlo»Solución 1: Añade .. para ignorar el resto
Sección titulada «Solución 1: Añade .. para ignorar el resto»Elige esta la mayoría de las veces. Si solo necesitas algunos campos, termina el patrón con ... Funciona en let, match, if let y en los parámetros de funciones, y tiene que ir al final.
struct Order { id: u32, item: String, quantity: u32, paid: bool,}
fn main() { let order = Order { id: 1, item: String::from("teclado"), quantity: 2, paid: true }; let Order { item, quantity, .. } = order; // ✅ `..` se salta `id` y `paid` println!("{} x {}", quantity, item);
let orders = [ Order { id: 2, item: String::from("auriculares"), quantity: 1, paid: false }, Order { id: 3, item: String::from("monitor"), quantity: 1, paid: true }, ]; for order in &orders { match order { Order { paid: true, item, .. } => println!("listo para enviar: {}", item), Order { id, .. } => println!("el pedido #{} espera el pago", id), } }}Salida:
2 x tecladoel pedido #2 espera el pagolisto para enviar: monitorFíjate en paid: true en el primer brazo: en un patrón, un campo también se puede comparar con un valor, y .. se sigue encargando de los demás.
Solución 2: Nombra el campo que falta, o ignóralo por su nombre con _
Sección titulada «Solución 2: Nombra el campo que falta, o ignóralo por su nombre con _»Elige esta cuando de verdad necesitas el campo, o cuando quieres que el patrón se rompa si más adelante se añade un campo. El mismo error aparece en un match sobre una variante de enum con campos con nombre:
error[E0027]: pattern does not mention field `y` --> src/main.rs:9:9 |9 | Message::Move { x } => println!("move to x = {}", x), // ❌ `y` is not mentioned | ^^^^^^^^^^^^^^^^^^^ missing field `y`Aquí el patrón no menciona el campo y, y la etiqueta lo repite: falta el campo y.
El programa que hay detrás:
enum Message { Move { x: i32, y: i32 }, Quit,}
fn main() { let m = Message::Move { x: 1, y: 2 }; match m { Message::Move { x } => println!("move to x = {}", x), // ❌ `y` is not mentioned Message::Quit => println!("quit"), }}Un movimiento tiene dos coordenadas, y el código debería usar las dos. Así que nombra y. Cuando un campo de verdad no importa, y: _ lo dice en voz alta, y aun así lo nombra:
enum Message { Move { x: i32, y: i32 }, Quit,}
fn main() { let messages = [Message::Move { x: 1, y: 2 }, Message::Move { x: 5, y: 0 }, Message::Quit]; for m in &messages { match m { Message::Move { x, y: 0 } => println!("deslízate por el suelo hasta x = {}", x), Message::Move { x, y } => println!("muévete a ({}, {})", x, y), // ✅ los dos campos Message::Quit => println!("salir"), } }
// todos los campos nombrados: añadir un campo a `Move` romperá esto a propósito if let Message::Move { x, y: _ } = &messages[0] { println!("primera x = {}", x); }}Salida:
muévete a (1, 2)deslízate por el suelo hasta x = 5salirprimera x = 1Si nombras un campo solo para ignorarlo, escribe y: _, no un simple y. Un y que nunca usas da un aviso de “unused variable” (variable sin usar).
Solución 3: Corrige un nombre de campo mal escrito
Sección titulada «Solución 3: Corrige un nombre de campo mal escrito»Elige esta cuando E0027 aparece junto con E0026 en la misma línea. Por ejemplo, Shape::Circle { r } para una variante cuyo campo es radius da los dos: E0026 por r (ese campo no existe) y E0027 por radius (no se menciona). El help de E0027 te sugerirá añadir radius al lado de r, pero eso no es lo que quieres. La solución real es cambiar el nombre equivocado: Shape::Circle { radius }, o Shape::Circle { radius: r } para mantener el nombre corto de la variable. Entonces los dos errores desaparecen a la vez. Mira la página de E0026 para ver ejemplos.
Dónde lo verás normalmente
Sección titulada «Dónde lo verás normalmente»Después de añadir un campo a un struct. Añades created_at a Order, y cada patrón que nombraba todos los campos ahora da E0027. Es la comprobación haciendo su trabajo. Decide en cada caso: ¿este código necesita created_at? Si es así, nómbralo; si no, añade ...
Parámetros de funciones. fn print_order(&Order { item, quantity }: &Order) también da E0027. Solución: &Order { item, quantity, .. }. Mira Patrones en let y en los parámetros de funciones.
Tuple structs y variantes de tupla. Para struct Color(u8, u8, u8);, el patrón Color(r) también está incompleto, pero rustc lo informa como E0023, “this pattern has 1 field, but the corresponding tuple struct has 3 fields” (este patrón tiene 1 campo, pero el tuple struct correspondiente tiene 3). La solución sigue la misma idea: Color(r, ..) o Color(r, _, _).
Errores relacionados
Sección titulada «Errores relacionados»- E0026: struct or variant does not have a field named x: un nombre de campo en el patrón que no existe. A menudo aparece junto con E0027.
- E0063: missing field in initializer: la misma idea al crear un struct: cada campo necesita un valor (o
..Default::default()). - E0004: non-exhaustive patterns: un
matchque no cubre todas las variantes, mientras que E0027 trata de todos los campos. E0023: this pattern has N fields, but the corresponding tuple struct has M fields: la versión para tuple structs (mira más arriba).- 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. struct Point { x: i32, y: i32, z: i32 }. ¿Qué patrón compila y te da solo x?
2. ¿Qué diferencia hay entre Order { item, .. } y Order { item, id: _, quantity: _, paid: _ }?
3. Te sale E0026 por r y E0027 por radius en la misma línea. ¿Cuál es la mejor solución?
Puntuación: 0 / 3
Para leer más
Sección titulada «Para leer más»- E0027 — 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 “Ignoring Remaining Parts of a Value with
..” (ignorar el resto de un valor con..). También existe una traducción al español de la comunidad del libro. - Destructuring structs — Rust by Example (en inglés): patrones de structs con
..que puedes ejecutar. - Patterns — The Rust Reference (en inglés): las reglas exactas de los patrones de structs y del patrón de resto
...