Salta ai contenuti

Errore Rust E0425: cannot find value in this scope (nome non trovato)

L’errore E0425 significa che Rust ha cercato un nome in un punto preciso del tuo codice e lì non l’ha trovato. È uno degli errori più comuni in assoluto, e si risolve quasi sempre in fretta: di solito è un errore di battitura, una variabile che vive dentro un altro blocco, o una funzione che ha bisogno del percorso del suo modulo. Questa pagina fa parte della guida agli errori del compilatore.

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);
| +

Il compilatore ti dice: «non trovo il valore total_scor in questo scope», e aggiunge che esiste una variabile locale con un nome simile.

Questo è il programma che l’ha prodotto:

fn main() {
let total_score = 42;
println!("Final score: {}", total_scor);
}

I segni ^^^^ indicano il nome che Rust non è riuscito a trovare: total_scor alla riga 3. «In this scope» (in questo scope) significa «dal punto in cui si trova questa riga». Rust ha controllato ogni variabile, funzione e import visibile in quel punto, e nessuno aveva quel nome.

Leggi anche la riga help:. Qui rustc ha notato una variabile con un nome simile (total_score) e ti mostra perfino la lettera mancante con un +. Quando vedi «a local variable with a similar name exists», è un errore di battitura.

È come chiamare «Gianni!» in una stanza quando il tuo amico si chiama Giovanni. Lui è proprio lì, ma nessuno risponde a «Gianni».

Lo stesso errore compare anche come cannot find function ... in this scope quando il nome che manca è una funzione che chiami.

Rust decide, prima che il programma parta, a che cosa si riferisce ogni nome. Una variabile esiste solo dalla sua riga let fino alla } di chiusura del blocco in cui è dichiarata. Quello è il suo scope (ambito). Fuori da quella zona il nome semplicemente non esiste.

Molti linguaggi ti lascerebbero passare, e lo scopriresti più tardi. In JavaScript un errore di battitura può creare in silenzio una nuova variabile globale o darti undefined. In Python avresti un NameError durante l’esecuzione, magari solo nell’unico percorso del codice che i tuoi test non toccano mai. Rust lo scopre durante la compilazione, ogni volta.

Le funzioni seguono la stessa idea con i moduli: una funzione dentro mod billing non è visibile da main finché non ne scrivi il percorso o non la importi con use.

Sceglila quando la riga help: dice che esiste un nome simile. È di gran lunga la causa più comune. In Rust i nomi distinguono anche tra maiuscole e minuscole, quindi Total_score e total_score sono nomi diversi.

fn main() {
let total_score = 42;
println!("Punteggio finale: {}", total_score);
}

Output:

Punteggio finale: 42
▶ Provalo tu

Soluzione 2: dichiara la variabile dove entrambi i punti possono vederla

Sezione intitolata “Soluzione 2: dichiara la variabile dove entrambi i punti possono vederla”

Sceglila quando l’help dice «the binding is available in a different scope in the same function» (il nome esiste, ma in un altro scope della stessa funzione). Hai creato la variabile dentro un ciclo o un blocco if, e poi l’hai usata dopo la }. La versione sbagliata è questa:

fn main() {
let prices = [120, 300, 80];
for price in prices {
let with_tax = price + price / 10;
println!("{with_tax}");
}
println!("Ultimo prezzo con le tasse: {}", with_tax); // error[E0425]
}

with_tax viene creata da zero a ogni giro del ciclo e buttata via alla } del ciclo. Se ti serve un valore dopo il ciclo, dichiaralo prima del ciclo e aggiornalo 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!("Ultimo prezzo con le tasse: {}", last_with_tax);
}

Output:

132
330
88
Ultimo prezzo con le tasse: 88
▶ Provalo tu

La stessa soluzione funziona se hai usato una variabile prima della sua riga let. Rust legge dall’alto in basso, quindi basta spostare il let più in alto.

Soluzione 3: scrivi il percorso della funzione, o aggiungi un use

Sezione intitolata “Soluzione 3: scrivi il percorso della funzione, o aggiungi un use”

Sceglila per cannot find function quando la funzione vive in un altro modulo. Rust stampa:

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;
|

Il compilatore non trova la funzione e ti suggerisce di importarla. Puoi chiamarla con il percorso completo (billing::total_with_tax(50.0)) oppure aggiungere la riga use suggerita da rustc:

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}");
}

Output:

60
▶ Provalo tu

La funzione deve anche essere pub. Senza, otterresti un errore diverso (E0603, «function is private»). Vedi Moduli per capire come funzionano i percorsi e use.

Sceglila dentro un metodo, quando il nome che manca è uno dei campi della tua struct. Se vieni da Java o C#, è naturale scrivere count e aspettarsi che indichi il campo. In Rust scrivi sempre self.count. rustc dice: help: you might have meant to use the available field (forse intendevi usare il campo disponibile).

struct Counter {
count: u32,
}
impl Counter {
fn report(&self) {
println!("Conteggio: {}", self.count);
}
}
fn main() {
let c = Counter { count: 3 };
c.report();
}

Output:

Conteggio: 3
▶ Provalo tu
  • Una variabile assegnata dentro un if. if balance > 50 { let bonus = 10; } e poi println!("{}", bonus) falliscono, perché bonus è morta alla }. Soluzione: fai produrre il valore all’if, let bonus = if balance > 50 { 10 } else { 0 };.

  • Chiamare un costruttore senza il suo tipo. let p = new("ferris"); dà cannot find function `new` in this scope. Soluzione: new appartiene al tipo, quindi scrivi Player::new("ferris").

  • Usare self in una funzione che non ha il parametro self. È il cugino stretto di E0425, 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

    Il compilatore dice che questa funzione non ha un parametro self, e che self è una parola chiave disponibile solo nei metodi che ce l’hanno. Soluzione: aggiungi un parametro self. rustc suggerisce &self, ma questa funzione modifica un campo, quindi le serve fn reset(&mut self).

Verifica veloce

1. rustc dice "help: a local variable with a similar name exists". Qual è la causa più probabile?

2. Scrivi let found = true; dentro un ciclo for e usi found dopo il ciclo. Perché fallisce?

3. Una funzione send vive in mod mailer. Quale riga permette a main di chiamarla come send()?

Punteggio: 0 / 3