Pular para o conteúdo

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.

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 ^^^^ 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.

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.

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: 42
▶ Experimente você mesmo

Correçã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:

132
330
88
Último preço com imposto: 88
▶ Experimente você mesmo

A 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:

60
▶ Experimente você mesmo

A 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.

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: 3
▶ Experimente você mesmo
  • Uma variável criada dentro de um if. if balance > 50 { let bonus = 10; } seguido de println!("{}", bonus) falha, porque bonus morreu no }. Correção: faça o if produzir 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: new pertence ao tipo, então escreva Player::new("ferris").

  • Usar self numa função que não tem parâmetro self. 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` parameter
    7 | self.count = 0;
    | ^^^^ `self` value is a keyword only available in methods with a `self` parameter

    O compilador avisa que essa função não tem parâmetro self e que self só existe em métodos que o recebem. Correção: acrescente um parâmetro self. O rustc sugere &self, mas esta função altera um campo, então ela precisa de fn reset(&mut self).

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