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.
Il messaggio di errore
Sezione intitolata “Il messaggio di errore”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);}Cosa significa
Sezione intitolata “Cosa significa”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.
Perché Rust si comporta così
Sezione intitolata “Perché Rust si comporta così”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.
Come risolverlo
Sezione intitolata “Come risolverlo”Soluzione 1: correggi l’ortografia
Sezione intitolata “Soluzione 1: correggi l’ortografia”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: 42Soluzione 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:
13233088Ultimo prezzo con le tasse: 88La 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:
60La funzione deve anche essere pub. Senza, otterresti un errore diverso (E0603, «function is private»). Vedi Moduli per capire come funzionano i percorsi e use.
Soluzione 4: aggiungi self. davanti a un campo
Sezione intitolata “Soluzione 4: aggiungi self. davanti a un campo”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: 3Dove lo incontri di solito
Sezione intitolata “Dove lo incontri di solito”-
Una variabile assegnata dentro un
if.if balance > 50 { let bonus = 10; }e poiprintln!("{}", 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:newappartiene al tipo, quindi scriviPlayer::new("ferris"). -
Usare
selfin una funzione che non ha il parametroself. È 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` parameter7 | self.count = 0;| ^^^^ `self` value is a keyword only available in methods with a `self` parameterIl compilatore dice che questa funzione non ha un parametro
self, e cheselfè una parola chiave disponibile solo nei metodi che ce l’hanno. Soluzione: aggiungi un parametroself. rustc suggerisce&self, ma questa funzione modifica un campo, quindi le servefn reset(&mut self).
Errori correlati
Sezione intitolata “Errori correlati”- E0599: no method found: il nome che chiami come metodo non esiste su quel tipo.
- E0382: use of moved value: la variabile esiste, ma il suo valore è stato spostato altrove.
- E0308: mismatched types: il nome è stato trovato, ma ha il tipo sbagliato.
- E0277: trait bound not satisfied: a un tipo manca un trait che serve a un certo codice.
- Tutti gli errori del compilatore: l’elenco completo, con un breve riassunto di ognuno.
Verifica veloce
Sezione intitolata “Verifica veloce”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
Per approfondire
Sezione intitolata “Per approfondire”- E0425 — Rust error codes index (in inglese): la spiegazione ufficiale, con altri esempi.
- Bringing Paths into Scope with use — The Rust Book (in inglese): come
userende visibili le funzioni di altri moduli. - Scope and Shadowing — Rust by Example (in inglese): brevi esempi di dove una variabile nasce e muore.
- Method Syntax — The Rust Book (in inglese): perché i metodi usano
selfe come raggiungere i campi attraverso di esso. - E0424 — Rust error codes index (in inglese): l’errore correlato per l’uso di
selffuori da un metodo.