Rust-Fehler E0432: unresolved import (Import nicht gefunden)
E0432 bedeutet: Eine deiner use-Zeilen zeigt auf etwas, das Rust nicht finden kann. Vielleicht steht das Crate noch nicht in Cargo.toml. Vielleicht steckt ein kleiner Tippfehler im Pfad. Oder es gibt zwar eine Datei, aber Rust weiß nicht, dass sie ein Modul ist. Der Fehler sieht bedrohlich aus, lässt sich aber fast immer mit einer einzigen Zeile beheben – und der Compiler sagt dir meistens auch, mit welcher. Diese Seite gehört zur Reihe Rust-Compilerfehler einfach erklärt.
Die Fehlermeldung
Abschnitt betitelt „Die Fehlermeldung“error[E0432]: unresolved import `rand` --> src/main.rs:1:5 |1 | use rand::random_range; | ^^^^ use of unresolved module or unlinked crate `rand` | = help: if you wanted to use a crate named `rand`, use `cargo add rand` to add it to your `Cargo.toml`Auf Deutsch heißt das ungefähr: „Der Import rand lässt sich nicht auflösen – es gibt kein Modul und kein eingebundenes Crate mit diesem Namen.“ Dieses Programm erzeugt die Meldung, und zwar in einem frischen cargo new-Projekt, in dem unter [dependencies] noch nichts steht:
use rand::random_range;
fn main() { let roll = random_range(1..=6); println!("You rolled {roll}");}Der Text unter den ^^^^ ändert sich je nach Ursache. Jede dieser Meldungen ist E0432, und jede führt zu einer anderen Lösung weiter unten:
Was unter den ^^^^ steht |
Was meistens schiefgelaufen ist | Lösung |
|---|---|---|
use of unresolved module or unlinked crate |
Das Crate fehlt in Cargo.toml, oder eine Datei hat keine mod-Zeile |
Lösung 1 oder 3 |
could not find `collection` in `std` |
ein Tippfehler mitten im Pfad | Lösung 2 |
no `Hashmap` in `collections` |
ein Tippfehler (oder falsche Groß-/Kleinschreibung) im letzten Namen | Lösung 2 |
could not find `inventory` in the crate root |
ein crate::-Pfad zu einem Modul, das nicht deklariert ist |
Lösung 3 |
no external crate |
Der Pfad beginnt im falschen Modul | Lösung 4 |
Was sie bedeutet
Abschnitt betitelt „Was sie bedeutet“Eine use-Zeile ist eine Abkürzung. use rand::random_range; heißt: „Ab jetzt bedeutet random_range das Ding unter rand::random_range.“ Bevor Rust diese Abkürzung anlegen kann, muss es den Pfad Stück für Stück ablaufen: erst rand finden, dann darin random_range.
Die ^^^^ markieren das erste Stück, das nicht geklappt hat. Hier ist es rand, gleich das erste Glied. Rust hat also nie nach random_range gesucht. Die Zeile help: vermutet den Grund: rand ist ein Crate von crates.io, und dieses Projekt hat es noch nicht hinzugefügt.
Das ist, als würdest du einem Taxifahrer die Adresse „Hafenstraße 12, Springfeld“ geben. Stimmt der Ortsname nicht, kann er gar nicht erst anfangen, die Straße zu suchen.
Warum Rust das macht
Abschnitt betitelt „Warum Rust das macht“Rust löst jeden Pfad beim Kompilieren auf, nicht erst beim Ausführen. Nichts wird „auf Verdacht“ geladen. Dein Code sieht nur drei Arten von Dingen: Crates, die in Cargo.toml stehen (plus std), Module, die du mit mod deklariert hast, und die Elemente darin. Nennt eine use-Zeile etwas außerhalb davon, hört Rust sofort auf, statt zu raten.
Das ist gut so. Ein falsch geschriebener Import in Python oder JavaScript fällt oft erst auf, wenn diese Zeile endlich ausgeführt wird – vielleicht in Produktion. In Rust lässt sich das Programm gar nicht erst bauen. Außerdem kann sich so nie ein Crate in dein Programm schleichen, das du nicht selbst hinzugefügt hast.
Seit der Edition 2018 beginnt ein use-Pfad an einer dieser Stellen: beim Namen eines Crates (std, rand), bei crate (die Wurzel deines eigenen Crates), bei self (das aktuelle Modul), bei super (das übergeordnete Modul) oder bei einem Modul, das im aktuellen Modul deklariert ist. Die Lektion Module erklärt das ausführlich, und Cargo und Crates erklärt Abhängigkeiten.
So behebst du den Fehler
Abschnitt betitelt „So behebst du den Fehler“Lösung 1: Das Crate mit cargo add hinzufügen
Abschnitt betitelt „Lösung 1: Das Crate mit cargo add hinzufügen“Nimm diese Lösung, wenn das erste Glied ein Crate von crates.io ist, etwa rand, serde oder regex, und die help:-Zeile cargo add erwähnt. Das ist die häufigste Ursache, besonders wenn du Code aus einem Blogartikel kopierst. Führe das im Ordner aus, in dem Cargo.toml liegt:
cargo add randCargo sucht die neueste Version und trägt für dich eine Zeile in Cargo.toml ein:
[dependencies]rand = "0.10.3"Jetzt lässt sich derselbe Code bauen. Diese Version gibt statt des Wurfs selbst eine Prüfung aus, damit die Ausgabe immer gleich ist:
use rand::random_range;
fn main() { let roll = random_range(1..=6); println!("Wurf liegt zwischen 1 und 6: {}", (1..=6).contains(&roll));}Ausgabe:
Wurf liegt zwischen 1 und 6: trueZwei Dinge bringen Leute hier oft durcheinander. Erstens: Crate-Namen mit Bindestrich schreibst du im Code mit Unterstrich. Du führst cargo add tracing-subscriber aus, schreibst aber use tracing_subscriber::.... Zweitens: Ist das Crate eine Abhängigkeit deines Workspaces, muss es trotzdem in der Cargo.toml des Pakets stehen, das es benutzt.
Lösung 2: Die Schreibweise des Pfads korrigieren
Abschnitt betitelt „Lösung 2: Die Schreibweise des Pfads korrigieren“Nimm diese Lösung, wenn unter den ^^^^ could not find `X` in `Y` oder no `X` in `Y` steht. Irgendetwas in der Mitte oder am Ende des Pfads ist falsch geschrieben. Ein Klassiker:
error[E0432]: unresolved import `std::collection` --> src/main.rs:1:10 |1 | use std::collection::HashMap; | ^^^^^^^^^^ could not find `collection` in `std`Rust findet collection nicht in std. Das Modul heißt collections, mit s. Auch die Groß- und Kleinschreibung zählt: use std::collections::Hashmap; schlägt fehl mit no `Hashmap` in `collections`, und rustc ergänzt help: a similar name exists in the module (im Modul gibt es einen ähnlichen Namen) mit der richtigen Schreibweise. Der korrigierte Import:
use std::collections::HashMap;
fn main() { let mut stock: HashMap<&str, u32> = HashMap::new(); stock.insert("Äpfel", 12); println!("{:?}", stock.get("Äpfel"));}Ausgabe:
Some(12)Wenn du den genauen Pfad nicht kennst, such in der Dokumentation der Standardbibliothek (auf Englisch). Die Seite jedes Elements zeigt oben seinen vollen Pfad. Mehr zu diesem Typ findest du unter HashMaps.
Lösung 3: Das Modul mit mod deklarieren
Abschnitt betitelt „Lösung 3: Das Modul mit mod deklarieren“Nimm diese Lösung, wenn du eine neue Datei angelegt hast, zum Beispiel src/inventory.rs, und use inventory::... sie nicht findet. In Rust ist eine Datei kein Modul, solange keine übergeordnete Datei sie deklariert. Dein Projekt sieht so aus:
src/├── main.rs use inventory::count_items; ← kein `mod inventory;`└── inventory.rs pub fn count_items() -> u32 { 42 }Und rustc sagt dir genau, was fehlt:
error[E0432]: unresolved import `inventory` --> src/main.rs:1:5 |1 | use inventory::count_items; | ^^^^^^^^^ use of unresolved module or unlinked crate `inventory` |help: to make use of source file src/inventory.rs, use `mod inventory` in this file to declare the module |1 + mod inventory; |Die Hilfe heißt: Um die Datei src/inventory.rs zu benutzen, deklariere das Modul in dieser Datei mit mod inventory. Schreib also mod inventory; oben in src/main.rs (oder in src/lib.rs, wenn das Modul zu deiner Bibliothek gehört). Stattdessen use crate::inventory::count_items; zu schreiben hilft nicht. Das schlägt fehl mit could not find `inventory` in the crate root, weil das Modul immer noch nicht deklariert ist.
Im Playground steht alles in einer einzigen Datei. Deshalb wird das Modul hier direkt mit mod inventory { ... } geschrieben. Es funktioniert genauso wie die eigene Datei:
mod inventory { pub fn count_items() -> u32 { 42 }}
use inventory::count_items;
fn main() { println!("Artikel auf Lager: {}", count_items());}Ausgabe:
Artikel auf Lager: 42Deklariere jedes Modul einmal, in seinem übergeordneten Modul. Andere Dateien erreichen es dann mit use crate::inventory::.... Schreib mod inventory; nicht in jede Datei, die es benutzt.
Lösung 4: Den Pfad an der richtigen Stelle beginnen
Abschnitt betitelt „Lösung 4: Den Pfad an der richtigen Stelle beginnen“Nimm diese Lösung, wenn der Import in einem Modul steht und das Element in einem anderen Modul deines eigenen Crates liegt. Hier liegt receipt in shop und möchte shop::store_name benutzen:
mod shop { pub fn store_name() -> &'static str { "Ferris Fruits" }
pub mod receipt { use store_name; // ❌ sucht an der falschen Stelle
pub fn header() -> String { format!("== {} ==", store_name()) } }}error[E0432]: unresolved import `store_name` --> src/main.rs:7:13 |7 | use store_name; // ❌ sucht an der falschen Stelle | ^^^^^^^^^^ no external crate `store_name`Rust meldet: Es gibt kein externes Crate namens store_name. Ein einfacher Name am Anfang eines use-Pfads bedeutet „ein Crate oder etwas, das genau hier in diesem Modul deklariert ist“. store_name ist beides nicht, also hat Rust nach einem Crate mit diesem Namen gesucht. Sag Rust stattdessen, wo es anfangen soll:
| Präfix | Beginnt bei | Beispiel |
|---|---|---|
crate:: |
der Wurzel deines Crates (main.rs oder lib.rs) |
use crate::shop::prices::price_of; |
super:: |
dem übergeordneten Modul | use super::store_name; |
self:: |
dem aktuellen Modul | use self::lines::line; |
Alle drei in einem Programm:
mod shop { pub fn store_name() -> &'static str { "Ferris Fruits" }
pub mod prices { pub fn price_of(item: &str) -> u32 { if item == "Apfel" { 3 } else { 5 } } }
pub mod receipt { use super::store_name; // übergeordnetes Modul: shop use crate::shop::prices::price_of; // ab der Wurzel des Crates use self::layout::line; // Kind dieses Moduls
mod layout { pub fn line(item: &str, price: u32) -> String { format!("{item}: {price}") } }
pub fn print(item: &str) { println!("== {} ==", store_name()); println!("{}", line(item, price_of(item))); } }}
fn main() { shop::receipt::print("Apfel");}Ausgabe:
== Ferris Fruits ==Apfel: 3use layout::line; würde hier auch funktionieren, weil layout im aktuellen Modul deklariert ist. self:: macht das nur ausdrücklich. Im Zweifel funktioniert crate:: mit dem vollen Pfad von überall in deinem Crate, und rustc schlägt es oft auch vor: help: a similar path exists (es gibt einen ähnlichen Pfad), gefolgt von der crate::-Version.
Wo du ihn oft siehst
Abschnitt betitelt „Wo du ihn oft siehst“Code, der für eine ältere Crate-Version geschrieben wurde. Viele Tutorials benutzen rand 0.8. Mit rand 0.10 bekommst du:
error[E0432]: unresolved import `rand::thread_rng` --> src/main.rs:1:5 |1 | use rand::thread_rng; | ^^^^^^^^^^^^^^^^ no `thread_rng` in the rootRust findet thread_rng nicht auf der obersten Ebene des Crates. Lösung: Schau in die Doku des Crates auf docs.rs, und zwar für die Version, die in deiner Cargo.toml steht. Hier heißt der neue Name rand::rng(). Siehe Zufallszahlen.
Ein Paket mit main.rs und lib.rs. Das sind zwei getrennte Crates. In main.rs bedeutet crate:: das Binary. Deshalb schlägt use crate::inventory::count_items; fehl mit could not find `inventory` in the crate root, obwohl lib.rs pub mod inventory; enthält. Lösung: Nimm den Paketnamen, use shop_app::inventory::count_items; (Bindestriche werden zu Unterstrichen).
Das Element existiert, ist aber privat. Das ist ein anderer Fehler, E0603, nicht E0432:
error[E0603]: function `count_items` is private --> src/main.rs:7:16 |7 | use inventory::count_items; | ^^^^^^^^^^^ private functionDie Funktion count_items ist privat. Lösung: Schreib pub vor das fn (und vor jedes mod auf dem Weg dorthin, denn ein privates Modul ergibt module `prices` is private). Siehe Module.
Verwandte Fehler
Abschnitt betitelt „Verwandte Fehler“- E0433: Ein Pfad in deinem Code (etwa
HashMap::new()oderrand::rng()) lässt sich nicht auflösen. Gleiche Ursachen, aber nicht in eineruse-Zeile. - E0425: Ein Wert oder eine Funktion wird nicht gefunden. Oft hilft dieselbe
use-Zeile. - E0603: Der Import wurde gefunden, ist aber privat. Ergänze
pub. - E0463:
can't find crate(Crate nicht gefunden). Den bekommst du beiextern crate rand;, wenn das Crate nicht inCargo.tomlsteht. - Alle Compilerfehler: die vollständige Liste der Fehlerseiten.
Kurzer Check
Abschnitt betitelt „Kurzer Check“Kurzer Check
1. Du hast use serde::Serialize; in ein neues Projekt kopiert und bekommst E0432: Das Crate serde sei „unresolved“ oder „unlinked“. Was hilft?
2. Du hast src/billing.rs angelegt, aber use billing::total; in main.rs schlägt fehl. Was fehlt?
3. In mod shop { mod receipt { ... } }: Wie importiert receipt eine Funktion, die direkt in shop definiert ist?
Punkte: 0 / 3
Weiterlesen
Abschnitt betitelt „Weiterlesen“- E0432 – Rust error codes index (auf Englisch): die offizielle Erklärung, auch dazu, wie sich Pfade mit Rust 2018 geändert haben.
- Pfade in den Gültigkeitsbereich bringen mit dem Schlüsselwort use – Das Rust-Buch: wie
usefunktioniert, mit externen Paketen und verschachtelten Pfaden. - Mit Pfaden auf ein Element im Modulbaum verweisen – Das Rust-Buch: absolute
crate::-Pfade, relative Pfade undsuper. - Module in verschiedene Dateien aufteilen – Das Rust-Buch: wo
modhingehört, wenn ein Modul in einer eigenen Datei liegt. cargo add– The Cargo Book (auf Englisch): alle Optionen zum Hinzufügen von Abhängigkeiten, auch für Features.