Erro E0026 do Rust: struct or variant does not have a field named X (padrão)
O E0026 quer dizer: você está desmontando uma struct ou uma variante de enum num padrão, como Shape::Circle { r }, e um dos nomes de campo que você escreveu não existe. É a versão para padrões do E0560 e do E0559, que pegam o mesmo engano quando você cria um valor. O rustc normalmente diz o nome certo numa linha help:, então a correção muitas vezes é uma palavra só. (Esta página faz parte de Erros do compilador Rust explicados.)
A mensagem de erro
Seção intitulada “A mensagem de erro”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, // ❌ o campo se chama `radius` | ^ | | | variant `Shape::Circle` does not have this field | help: `Shape::Circle` has a field named `radius`Em português: “a variante Shape::Circle não tem um campo chamado r”. O rótulo diz que a variante não tem este campo, e a ajuda diz que Shape::Circle tem um campo chamado radius.
Este é o programa que gera o erro:
enum Shape { Circle { radius: f64 }, Rectangle { width: f64, height: f64 },}
fn area(shape: &Shape) -> f64 { match shape { Shape::Circle { r } => 3.14 * r * r, // ❌ o campo se chama `radius` Shape::Rectangle { width, height } => width * height, }}
fn main() { println!("{}", area(&Shape::Circle { radius: 1.0 }));}Você também vai ver um segundo erro na mesma linha: o E0027, “pattern does not mention field radius” (o padrão não menciona o campo radius). É o mesmo engano visto pelo outro lado. O Rust encontrou um campo que você citou e que não existe (r) e um campo real que você não citou (radius). Corrija o nome e os dois erros somem.
O que significa
Seção intitulada “O que significa”A primeira linha diz o nome da struct ou variante que você está comparando (Shape::Circle) e o campo que você escreveu (r). O ^ aponta para esse nome dentro das chaves do padrão.
Num padrão, os nomes dentro de { } são nomes de campos, e não nomes novos de variáveis que você pode escolher à vontade. Shape::Circle { r } é uma forma curta de Shape::Circle { r: r }: “pegue o campo chamado r e coloque numa variável chamada r”. Circle não tem nenhum campo chamado r, então o Rust para.
Embaixo da seta, o rustc dá uma destas dicas:
help: `Shape::Circle` has a field named `radius`(Shape::Circletem um campo chamadoradius): sobrou exatamente um campo que você não citou, então o rustc imagina que você quis dizer esse.help: a field with a similar name exists(existe um campo com um nome parecido): é erro de digitação, comonmaeem vez dename. O rustc mostra a linha corrigida.- Nenhuma dica: o rustc não conseguiu adivinhar. Olhe a definição da struct ou do enum para ver os nomes reais.
É como pedir a um bibliotecário “o livro da estante Ficção-ou-quase”. Ele sabe que você quer alguma estante, mas só pode ir até estantes que existem de verdade.
Por que o Rust faz isso
Seção intitulada “Por que o Rust faz isso”Um padrão como Shape::Circle { radius } é uma promessa: “quando o valor for um Circle, me dê o radius dele”. O Rust confere essa promessa com a definição na hora de compilar, então um padrão nunca pode pedir dados que não estão lá. Veja Desestruturando tuplas e structs.
Em linguagens sem essa verificação, ler uma chave que não existe dá undefined ou null, e o bug só aparece bem depois, longe do erro de digitação. Em Rust o erro de digitação não passa pelo compilador. Isso também protege você quando alguém renomeia um campo: todo padrão que ainda usa o nome antigo acende com E0026, então nenhum deles fica esquecido em silêncio.
Como corrigir
Seção intitulada “Como corrigir”Correção 1: Use o nome real do campo
Seção intitulada “Correção 1: Use o nome real do campo”Escolha esta na maioria das vezes. Use o nome que aparece na linha help:, ou olhe a definição. Nomes de campos diferenciam maiúsculas de minúsculas e são escritos em snake_case.
Um erro de digitação ganha a dica de “nome parecido” e a linha corrigida:
error[E0026]: struct `User` does not have a field named `nmae` --> src/main.rs:8:16 |8 | let User { nmae, age } = user; // ❌ erro de digitação: o campo é `name` | ^^^^ struct `User` does not have this field |help: a field with a similar name exists |8 - let User { nmae, age } = user; // ❌ erro de digitação: o campo é `name`8 + let User { name, age } = user; // ❌ erro de digitação: o campo é `name` |O rustc diz que a struct User não tem este campo e mostra a linha com o nome parecido que existe: name.
O programa por trás dele:
struct User { name: String, age: u32,}
fn main() { let user = User { name: String::from("Ferris"), age: 7 }; let User { nmae, age } = user; // ❌ erro de digitação: o campo é `name` println!("{} tem {} anos", nmae, age);}Escreva os nomes dos campos exatamente como na definição. Aí a forma curta funciona, e você ganha variáveis com os mesmos nomes:
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, // ✅ o nome real do 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`, e não `nmae` println!("{} tem {} anos", name, age);}Saída:
área: 12.56área: 12.00Ferris tem 7 anosCorreção 2: Mantenha o seu nome de variável com campo: nome
Seção intitulada “Correção 2: Mantenha o seu nome de variável com campo: nome”Escolha esta quando você gosta do nome curto r e só quer que a variável se chame assim. Escreva o nome real do campo, dois-pontos e depois o nome da sua variável: Shape::Circle { radius: r }. Leia como “pegue o campo radius e chame de 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`, variável `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!("pequeno: {:.2}", area(&small)); println!("largo: {:.2}", area(&wide));}Saída:
pequeno: 3.14largo: 25.00Isso também ajuda quando dois campos iriam se chocar com variáveis que você já tem, ou quando o nome do campo é comprido.
Correção 3: Confira se você está comparando a variante certa
Seção intitulada “Correção 3: Confira se você está comparando a variante certa”Escolha esta quando o campo que você escreveu existe, só que numa variante diferente. Cada variante de um enum tem os seus próprios campos. Aqui x pertence a Click, mas o braço compara com KeyPress:
error[E0026]: variant `Event::KeyPress` does not have a field named `x` --> src/main.rs:9:27 |9 | Event::KeyPress { x, .. } => format!("tecla em {}", x), // ❌ `x` pertence a `Click` | ^ | | | variant `Event::KeyPress` does not have this field | help: `Event::KeyPress` has a field named `key`O rustc diz que a variante Event::KeyPress não tem este campo, e que ela tem um campo chamado key.
O programa por trás dele:
enum Event { Click { x: i32, y: i32 }, KeyPress { key: char },}
fn describe(event: &Event) -> String { match event { Event::Click { x, y } => format!("clique em ({}, {})", x, y), Event::KeyPress { x, .. } => format!("tecla em {}", x), // ❌ `x` pertence a `Click` }}
fn main() { println!("{}", describe(&Event::KeyPress { key: 'a' }));}O palpite do rustc (key) é só “o único campo que você não citou”, então não aceite sem pensar. Pergunte a si mesmo o que este braço deveria fazer. Uma tecla pressionada não tem posição, então aqui a correção certa é usar o campo que KeyPress tem de verdade:
enum Event { Click { x: i32, y: i32 }, KeyPress { key: char },}
fn describe(event: &Event) -> String { match event { Event::Click { x, y } => format!("clique em ({}, {})", x, y), Event::KeyPress { key } => format!("tecla '{}' pressionada", key), // ✅ KeyPress tem `key` }}
fn main() { let events = [Event::Click { x: 10, y: 20 }, Event::KeyPress { key: 'a' }]; for event in &events { println!("{}", describe(event)); }}Saída:
clique em (10, 20)tecla 'a' pressionadaSe uma tecla pressionada deveria mesmo ter uma posição, acrescente os campos à variante: KeyPress { key: char, x: i32, y: i32 }. Aí todo lugar que cria um KeyPress também precisa preenchê-los (o rustc aponta cada um com E0063).
Onde você costuma ver esse erro
Seção intitulada “Onde você costuma ver esse erro”Depois de renomear um campo. Você renomeou r para radius no enum, e agora todo braço Shape::Circle { r } => ... dá E0026. Procure o nome antigo no projeto e atualize cada padrão, ou use radius: r para manter o nome antigo da variável.
Em if let e let. if let Some(User { nmae, .. }) = find_user() dá o mesmo erro. Acrescentar .. não ajuda aqui: o .. pula os campos que você não cita, mas todo nome que você escreve ainda precisa existir. Correção: User { name, .. }.
Chaves numa variante de tupla ou numa tuple struct. Para struct Point(i32, i32);, o padrão Point { x, y } não tem nomes de campos reais para comparar. O rustc avisa isso com outro código, o E0769, “tuple variant Point written as struct variant” (variante de tupla Point escrita como variante de struct), e sugere Point(x, y). Veja Desestruturando enums com dados.
Erros relacionados
Seção intitulada “Erros relacionados”- E0027: pattern does not mention field: o gêmeo do E0026, um campo real que o seu padrão deixou de fora. Muitas vezes aparece junto com o E0026.
- E0559: variant has no field named x: o mesmo nome errado ao criar uma variante de enum.
- E0560: struct has no field named x: o mesmo nome errado ao criar uma struct.
- E0609: no field on type: o mesmo nome errado ao ler um campo, como
user.nmae. - E0533: expected unit struct, unit variant or constant: a variante está certa, mas o padrão tem o formato errado (sem
{ }). - Todos os erros do compilador explicados
Teste o que aprendeu
Seção intitulada “Teste o que aprendeu”Teste o que aprendeu
1. Para enum Shape { Circle { radius: f64 } }, o que o padrão Shape::Circle { r } pede?
2. Você quer o campo radius numa variável chamada r. Qual padrão funciona?
3. User { nmae, .. } compila se o campo se chama name?
Pontuação: 0 / 3
Para saber mais
Seção intitulada “Para saber mais”- E0026 — Rust error codes index (em inglês): a explicação oficial deste erro.
- Pattern Syntax — The Rust Book (em inglês): como desestruturar structs e enums, incluindo
campo: variávele... - Destructuring structs — Rust by Example (em inglês): exemplos curtos para rodar de padrões de struct.
- Patterns — The Rust Reference (em inglês): as regras exatas dos padrões de struct e da forma curta de campo.