Zum Inhalt springen

Rust-Fehler E0425: cannot find value in this scope (Name nicht gefunden)

Fehler E0425 bedeutet: Rust hat an einer ganz bestimmten Stelle in deinem Code nach einem Namen gesucht und ihn dort nicht gefunden. Das ist einer der häufigsten Fehler überhaupt – und fast immer schnell behoben. Meistens steckt ein Tippfehler dahinter, eine Variable, die in einem anderen Block lebt, oder eine Funktion, der der Pfad zu ihrem Modul fehlt. Diese Seite gehört zur Reihe Rust-Compilerfehler einfach erklärt.

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

Auf Deutsch heißt das ungefähr: „Der Wert total_scor ist in diesem Gültigkeitsbereich nicht zu finden.“ Dieses Programm erzeugt die Meldung:

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

Die ^^^^ markieren den Namen, den Rust nicht finden konnte: total_scor in Zeile 3. „In this scope“ heißt „von dieser Zeile aus gesehen“. Rust hat alle Variablen, Funktionen und Importe geprüft, die an dieser Stelle sichtbar sind – und keiner davon hatte diesen Namen.

Lies auch die Zeile help:. Hier hat rustc eine Variable mit ähnlichem Namen entdeckt (total_score) und zeigt dir den fehlenden Buchstaben sogar mit einem +. Steht da „a local variable with a similar name exists“ (es gibt eine lokale Variable mit ähnlichem Namen), ist es ein Tippfehler.

Stell dir vor, du rufst quer durch den Raum „Jon!“, aber dein Freund heißt John. Er steht direkt neben dir, aber auf „Jon“ reagiert niemand.

Derselbe Fehler erscheint auch als cannot find function ... in this scope, wenn der fehlende Name eine Funktion ist, die du aufrufst.

Rust legt schon vor dem Start deines Programms fest, worauf sich jeder Name bezieht. Eine Variable existiert nur von ihrer let-Zeile bis zur schließenden } des Blocks, in dem sie angelegt wurde. Das ist ihr Gültigkeitsbereich (Scope). Außerhalb davon gibt es den Namen einfach nicht.

Viele Sprachen lassen dir so etwas durchgehen, und du merkst es erst später. In JavaScript kann ein Tippfehler still eine neue globale Variable anlegen oder dir undefined liefern. In Python bekommst du einen NameError erst zur Laufzeit – vielleicht nur in dem einen Codepfad, den deine Tests nie erreichen. Rust findet den Fehler beim Kompilieren, jedes Mal.

Für Funktionen gilt dieselbe Idee mit Modulen: Eine Funktion in mod billing ist von main aus erst sichtbar, wenn du ihren Pfad angibst oder sie mit use hereinholst.

Nimm diese Lösung, wenn die Zeile help: sagt, dass es einen ähnlichen Namen gibt. Das ist mit Abstand die häufigste Ursache. Achte auch auf Groß- und Kleinschreibung: Total_score und total_score sind zwei verschiedene Namen.

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

Ausgabe:

Endstand: 42
▶ Selbst ausprobieren

Lösung 2: Die Variable dort anlegen, wo beide Stellen sie sehen

Abschnitt betitelt „Lösung 2: Die Variable dort anlegen, wo beide Stellen sie sehen“

Nimm diese Lösung, wenn die Hilfe sagt: „the binding is available in a different scope in the same function“ (die Variable gibt es in einem anderen Gültigkeitsbereich derselben Funktion). Du hast die Variable in einer Schleife oder einem if-Block angelegt und benutzt sie nach der }. Die fehlerhafte Version sieht so aus:

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 entsteht bei jedem Schleifendurchlauf neu und wird an der } der Schleife wieder weggeworfen. Brauchst du einen Wert nach der Schleife, lege die Variable vor der Schleife an und aktualisiere sie darin:

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!("Letzter Preis mit Steuer: {}", last_with_tax);
}

Ausgabe:

132
330
88
Letzter Preis mit Steuer: 88
▶ Selbst ausprobieren

Dieselbe Lösung hilft, wenn du eine Variable vor ihrer let-Zeile benutzt hast. Rust liest von oben nach unten – schieb die let-Zeile also einfach nach oben.

Lösung 3: Den Pfad der Funktion angeben oder ein use ergänzen

Abschnitt betitelt „Lösung 3: Den Pfad der Funktion angeben oder ein use ergänzen“

Nimm diese Lösung bei cannot find function, wenn die Funktion in einem anderen Modul liegt. Rust meldet:

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

Die Hilfe schlägt vor, die Funktion zu importieren. Du kannst sie entweder mit ihrem vollen Pfad aufrufen (billing::total_with_tax(50.0)) oder die use-Zeile ergänzen, die rustc vorschlägt:

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

Ausgabe:

60
▶ Selbst ausprobieren

Die Funktion muss außerdem pub sein. Ohne pub bekommst du einen anderen Fehler (E0603, „function is private“, die Funktion ist privat). Wie Pfade und use funktionieren, erklärt die Seite Module.

Nimm diese Lösung in einer Methode, wenn der fehlende Name eines der Felder deines Structs ist. Wenn du von Java oder C# kommst, schreibst du ganz natürlich count und meinst damit das Feld. In Rust schreibst du immer self.count. rustc sagt dazu: help: you might have meant to use the available field (du wolltest wahrscheinlich das vorhandene Feld benutzen).

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

Ausgabe:

Zählerstand: 3
▶ Selbst ausprobieren
  • Eine Variable, die in einem if gesetzt wird. if balance > 50 { let bonus = 10; } und danach println!("{}", bonus) schlägt fehl, weil bonus an der } verschwunden ist. Lösung: Lass das if den Wert liefern – let bonus = if balance > 50 { 10 } else { 0 };.

  • Einen Konstruktor ohne seinen Typ aufrufen. let p = new("ferris"); ergibt cannot find function `new` in this scope. Lösung: new gehört zum Typ, also schreibst du Player::new("ferris").

  • self in einer Funktion ohne self-Parameter benutzen. Das ist ein enger Verwandter von E0425, nämlich 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

    rustc erklärt hier: Diese Funktion hat keinen self-Parameter, und self gibt es nur in Methoden mit einem solchen Parameter. Lösung: Füge einen self-Parameter hinzu. rustc schlägt &self vor, aber diese Funktion ändert ein Feld, sie braucht also fn reset(&mut self).

Kurzer Check

1. rustc sagt „help: a local variable with a similar name exists“. Was ist die wahrscheinlichste Ursache?

2. Du schreibst let found = true; in einer for-Schleife und benutzt found nach der Schleife. Warum klappt das nicht?

3. Eine Funktion send liegt in mod mailer. Mit welcher Zeile kann main sie als send() aufrufen?

Punkte: 0 / 3