Erro E0425 do Rust: cannot find value in this scope (nome não encontrado)
O E0425 quer dizer que o Rust procurou um nome num ponto exato do seu código e não o encontrou ali. É um dos erros mais comuns que existem, e quase sempre se resolve rápido: normalmente é um erro de digitação, uma variável que mora dentro de outro bloco ou uma função que precisa do caminho do módulo. Para os outros erros desta série, veja Erros do compilador Rust.
A mensagem de erro
Seção intitulada “A mensagem de erro”error[E0425]: cannot find value `total_scor` in this scope --> src/main.rs:3:33 |3 | println!("Final score: {}", total_scor); | ^^^^^^^^^^ |help: a local variable with a similar name exists |3 | println!("Final score: {}", total_score); | +Em português: “não foi possível encontrar o valor total_scor neste escopo”. O compilador aponta o nome que não existe e sugere uma variável com nome parecido.
Este é o programa que gera o erro:
fn main() { let total_score = 42; println!("Final score: {}", total_scor);}O que significa
Seção intitulada “O que significa”O ^^^^ marca o nome que o Rust não encontrou: total_scor, na linha 3. “In this scope” (neste escopo) quer dizer “a partir de onde esta linha está”. O Rust conferiu todas as variáveis, funções e imports visíveis naquele ponto, e nenhum tinha esse nome.
Leia também a linha help:. Aqui o rustc encontrou uma variável com nome parecido (total_score) e ainda mostra a letra que faltou com um +. Quando aparecer “a local variable with a similar name exists” (existe uma variável local com nome parecido), é erro de digitação.
É como chamar “Jon!” do outro lado da sala quando o nome do seu amigo é John. Ele está bem ali, mas ninguém responde por “Jon”.
O mesmo erro também aparece como cannot find function ... in this scope (função não encontrada neste escopo) quando o nome que falta é de uma função que você chamou.
Por que o Rust faz isso
Seção intitulada “Por que o Rust faz isso”O Rust decide, antes de o programa rodar, a que cada nome se refere. Uma variável só existe da linha do let até o } que fecha o bloco onde ela foi declarada. Esse é o escopo dela. Fora dessa região, o nome simplesmente não existe.
Muitas linguagens deixariam isso passar, e você só descobriria depois. Em JavaScript, um erro de digitação pode criar sem alarde uma nova variável global ou devolver undefined. Em Python você levaria um NameError em tempo de execução, talvez só naquele caminho do código que os seus testes nunca passam. O Rust pega o problema na compilação, sempre.
Funções seguem a mesma ideia com módulos: uma função dentro de mod billing não é visível em main até você escrever o caminho dela ou trazê-la com use.
Como corrigir
Seção intitulada “Como corrigir”Correção 1: Corrija a grafia
Seção intitulada “Correção 1: Corrija a grafia”Escolha esta quando a linha help: disser que existe um nome parecido. É de longe a causa mais comum. Os nomes em Rust também diferenciam maiúsculas de minúsculas, então Total_score e total_score são nomes diferentes.
fn main() { let total_score = 42; println!("Final score: {}", total_score);}Saída:
Final score: 42Correção 2: Declare a variável onde os dois lugares a enxerguem
Seção intitulada “Correção 2: Declare a variável onde os dois lugares a enxerguem”Escolha esta quando o help disser “the binding is available in a different scope in the same function” (o nome existe em outro escopo da mesma função). Você criou a variável dentro de um loop ou de um bloco if e a usou depois do }. A versão quebrada fica assim:
fn main() { let prices = [120, 300, 80]; for price in prices { let with_tax = price + price / 10; println!("{with_tax}"); } println!("Last price with tax: {}", with_tax); // error[E0425]}with_tax é criada do zero a cada volta do loop e jogada fora no } do loop. Se você precisa de um valor depois do loop, declare a variável antes dele e atualize-a lá dentro:
fn main() { let prices = [120, 300, 80]; let mut last_with_tax = 0;
for price in prices { let with_tax = price + price / 10; println!("{with_tax}"); last_with_tax = with_tax; }
println!("Último preço com imposto: {}", last_with_tax);}Saída:
13233088Último preço com imposto: 88A mesma correção vale se você usou uma variável antes da linha do let dela. O Rust lê de cima para baixo, então é só subir o let.
Correção 3: Escreva o caminho da função ou acrescente um use
Seção intitulada “Correção 3: Escreva o caminho da função ou acrescente um use”Escolha esta para cannot find function quando a função mora em outro módulo. O Rust mostra:
error[E0425]: cannot find function `total_with_tax` in this scope --> src/main.rs:8:17 |8 | let total = total_with_tax(50.0); | ^^^^^^^^^^^^^^ not found in this scope |help: consider importing this function |1 + use crate::billing::total_with_tax; |O compilador diz que a função não foi encontrada neste escopo e sugere importá-la. Você pode chamá-la pelo caminho completo (billing::total_with_tax(50.0)) ou acrescentar a linha use que o rustc sugere:
mod billing { pub fn total_with_tax(amount: f64) -> f64 { amount * 1.2 }}
use crate::billing::total_with_tax;
fn main() { let total = total_with_tax(50.0); println!("{total}");}Saída:
60A função também precisa ser pub. Sem isso, você teria outro erro (E0603, “function is private”, a função é privada). Veja Módulos para entender como caminhos e use funcionam.
Correção 4: Coloque self. na frente do campo
Seção intitulada “Correção 4: Coloque self. na frente do campo”Escolha esta dentro de um método, quando o nome que falta é um dos campos da sua struct. Para quem vem de Java ou C#, é natural escrever count e esperar que isso signifique o campo. Em Rust, você sempre escreve self.count. O rustc diz: help: you might have meant to use the available field (talvez você quisesse usar o campo disponível).
struct Counter { count: u32,}
impl Counter { fn report(&self) { println!("Contagem: {}", self.count); }}
fn main() { let c = Counter { count: 3 }; c.report();}Saída:
Contagem: 3Onde você costuma ver esse erro
Seção intitulada “Onde você costuma ver esse erro”-
Uma variável criada dentro de um
if.if balance > 50 { let bonus = 10; }seguido deprintln!("{}", bonus)falha, porquebonusmorreu no}. Correção: faça oifproduzir o valor,let bonus = if balance > 50 { 10 } else { 0 };. -
Chamar um construtor sem o tipo.
let p = new("ferris");dácannot find function `new` in this scope. Correção:newpertence ao tipo, então escrevaPlayer::new("ferris"). -
Usar
selfnuma função que não tem parâmetroself. Este é o primo próximo do E0425, o E0424:error[E0424]: expected value, found module `self`--> src/main.rs:7:9|6 | fn reset() {| ----- this function doesn't have a `self` parameter7 | self.count = 0;| ^^^^ `self` value is a keyword only available in methods with a `self` parameterO compilador avisa que essa função não tem parâmetro
selfe queselfsó existe em métodos que o recebem. Correção: acrescente um parâmetroself. O rustc sugere&self, mas esta função altera um campo, então ela precisa defn reset(&mut self).
Erros relacionados
Seção intitulada “Erros relacionados”- E0599: no method found: o nome que você chama como método não existe naquele tipo.
- E0382: use of moved value: a variável existe, mas o valor dela foi movido para outro lugar.
- E0308: mismatched types: o nome foi encontrado, mas tem o tipo errado.
- E0277: trait bound not satisfied: falta a um tipo um trait de que algum código precisa.
- Todos os erros do compilador: a lista completa, com um resumo curto de cada um.
Teste o que aprendeu
Seção intitulada “Teste o que aprendeu”Teste o que aprendeu
1. O rustc diz "help: a local variable with a similar name exists". Qual é a causa mais provável?
2. Você escreve let found = true; dentro de um loop for e usa found depois do loop. Por que falha?
3. Uma função send mora em mod mailer. Qual linha deixa main chamá-la como send()?
Pontuação: 0 / 3
Para saber mais
Seção intitulada “Para saber mais”- E0425 — Rust error codes index (em inglês): a explicação oficial, com mais exemplos.
- Bringing Paths into Scope with use — The Rust Book (em inglês): como o
usetorna visíveis as funções de outros módulos. - Scope and Shadowing — Rust by Example (em inglês): exemplos curtos de onde uma variável nasce e morre.
- Method Syntax — The Rust Book (em inglês): por que os métodos usam
selfe como chegar aos campos por meio dele. - E0424 — Rust error codes index (em inglês): o erro relacionado de usar
selffora de um método.