Rust-Fehler E0433: failed to resolve, use of undeclared type (unbekannter Typ)
E0433 bedeutet: Du hast einen Pfad wie HashMap::new() oder rand::rng() geschrieben, und Rust weiß nicht, was der erste Teil davon ist. Fast immer fehlt genau eine Zeile: ein use, eine Abhängigkeit in Cargo.toml oder eine mod-Deklaration. Die gute Nachricht: rustc druckt dir diese Zeile meistens schon zum Kopieren aus. Diese Seite gehört zur Reihe Rust-Compilerfehler einfach erklärt.
Die Fehlermeldung
Abschnitt betitelt „Die Fehlermeldung“error[E0433]: cannot find type `HashMap` in this scope --> src/main.rs:2:21 |2 | let mut stock = HashMap::new(); | ^^^^^^^ use of undeclared type `HashMap` |help: consider importing this struct |1 + use std::collections::HashMap; |Auf Deutsch heißt das ungefähr: „Der Typ HashMap ist hier nicht zu finden – er wurde nicht deklariert.“ Dieses Programm erzeugt die Meldung:
fn main() { let mut stock = HashMap::new(); stock.insert("apples", 12); println!("{:?}", stock.get("apples"));}Ältere Rust-Versionen geben denselben Fehler als „failed to resolve: use of undeclared type HashMap“ aus (Auflösung fehlgeschlagen: nicht deklarierter Typ). Je nachdem, was fehlt, kann die Beschriftung auch use of unresolved module or unlinked crate lauten (für ein Crate oder Modul) statt use of undeclared type. All das ist E0433, und du behebst es auf dieselbe Weise.
Was sie bedeutet
Abschnitt betitelt „Was sie bedeutet“Die ^^^^^^^ zeigen auf HashMap, also auf den Teil vor dem ::. Um HashMap::new() aufzurufen, muss Rust zuerst etwas finden, das HashMap heißt. Es hat alles durchsucht, was von Zeile 2 aus sichtbar ist, und nichts mit diesem Namen gefunden. Deshalb kann es gar nicht erst nach new suchen.
Das Wichtigste ist die Zeile help:. rustc hat die Standardbibliothek durchsucht, ein Struct namens HashMap in std::collections gefunden und zeigt dir die use-Zeile, die es sichtbar macht. 1 + bedeutet „füge das als Zeile 1 ein“.
Das ist, als würdest du in der Bibliothek nach „Kapitel 3 aus dem Buch“ fragen, ohne zu sagen, welches Buch. Kapitel 3 gibt es in vielen Büchern – aber zuerst braucht man den Titel.
Warum Rust das macht
Abschnitt betitelt „Warum Rust das macht“Nur eine kleine Menge von Namen ist in jeder Rust-Datei automatisch sichtbar. Diese Menge heißt Prelude (Vorspiel): Vec, String, Option, Some, None, Result, Ok, Err, Box und ein paar Traits. Alles andere, auch HashMap, HashSet, fs und Ordering, musst du mit use hereinholen oder mit dem vollen Pfad schreiben.
So bleibt die Prelude klein, und Namenskonflikte werden vermieden. Die Standardbibliothek hat zum Beispiel zwei verschiedene Ordering-Typen, und dein eigener Code hat vielleicht auch ein Duration oder ein Result. Rust rät nicht, welches du gemeint hast. Du sagst es einmal oben in der Datei, und jeder, der den Code liest, sieht, woher jeder Name kommt.
Dasselbe gilt für Crates und Module: Ein Crate existiert für deinen Code erst, wenn es in Cargo.toml steht, und ein Modul erst nach einer mod-Zeile. Siehe Module und Cargo und Crates.
So behebst du den Fehler
Abschnitt betitelt „So behebst du den Fehler“Lösung 1: Die use-Zeile ergänzen, die rustc vorschlägt
Abschnitt betitelt „Lösung 1: Die use-Zeile ergänzen, die rustc vorschlägt“Nimm diese Lösung, wenn in der help:-Zeile consider importing (importiere vielleicht) steht. Das ist mit Abstand die häufigste Lösung. Kopiere die vorgeschlagene Zeile an den Anfang der Datei:
use std::collections::HashMap;
fn main() { let mut stock = HashMap::new(); stock.insert("Äpfel", 12); println!("{:?}", stock.get("Äpfel"));}Ausgabe:
Some(12)Die andere Möglichkeit ist der volle Pfad direkt beim Aufruf, std::collections::HashMap::new(). Das funktioniert auch, aber dann musst du ihn überall wiederholen. Deshalb ist eine use-Zeile der übliche Weg. Mehr zu diesem Typ findest du unter HashMaps.
Bietet rustc mehrere Importe an (consider importing one of these, importiere vielleicht einen davon), lies sie, bevor du einen auswählst. Es sind verschiedene Typen mit demselben Namen, und nur einer davon ist der, den du meinst.
Lösung 2: Den Namen des Typs korrigieren oder den Typ deklarieren
Abschnitt betitelt „Lösung 2: Den Namen des Typs korrigieren oder den Typ deklarieren“Nimm diese Lösung, wenn der Name zu einem eigenen Typ gehört. Gibt es gar keine help:-Zeile, existiert der Typ noch nicht. Bei einem Tippfehler zeigt rustc auf den ähnlichen Namen:
error[E0433]: cannot find type `Invetory` in this scope --> src/main.rs:12:17 |12 | let stock = Invetory::new(); | ^^^^^^^^ use of undeclared type `Invetory` |help: a struct with a similar name exists |12 | let stock = Inventory::new(); | +Die Hilfe sagt: Es gibt ein Struct mit ähnlichem Namen. Das + unter der Zeile zeigt den fehlenden Buchstaben. Korrigiere die Schreibweise:
struct Inventory { items: Vec<String>,}
impl Inventory { fn new() -> Self { Inventory { items: Vec::new() } }}
fn main() { let stock = Inventory::new(); println!("{} Artikel", stock.items.len());}Ausgabe:
0 ArtikelErgibt Order::new() den Fehler E0433 ohne Vorschlag, hast du struct Order noch nicht geschrieben (oder es steht in einer Datei, die du nicht mit mod deklariert hast). Prüf auch die Großbuchstaben: inventory::new() und Inventory::new() sind verschiedene Namen.
Lösung 3: Das Modul nennen, in dem der Typ liegt
Abschnitt betitelt „Lösung 3: Das Modul nennen, in dem der Typ liegt“Nimm diese Lösung, wenn der Typ oder das Enum in einem Modul definiert ist und du ihn von außerhalb benutzt. Hier liegt das Enum in mod traffic, aber main schreibt Light::Green:
error[E0433]: cannot find type `Light` in this scope --> src/main.rs:11:15 |11 | let now = Light::Green; | ^^^^^ use of undeclared type `Light` |help: consider importing this enum | 1 + use crate::traffic::Light; |Importiere das Enum (oder schreib traffic::Light::Green). Beachte: Du importierst das Enum und schreibst danach trotzdem für jede Variante Light::Green:
mod traffic { #[derive(Debug)] pub enum Light { Red, Yellow, Green, }}
use crate::traffic::Light;
fn can_go(light: &Light) -> bool { match light { Light::Green => true, Light::Yellow | Light::Red => false, }}
fn main() { let now = Light::Green; println!("{now:?}: fahren = {}", can_go(&now));}Ausgabe:
Green: fahren = trueEin Pfad zu einer Variante hat genau zwei Teile: Enum::Variante. Schreibst du einen Teil zu viel, etwa Light::Red::Green, bekommst du E0433 mit cannot find module `Red` in `Light` und der Beschriftung `Red` is a variant, not a module (Red ist eine Variante, kein Modul). Siehe Enums.
Lösung 4: Das Crate hinzufügen oder das Modul deklarieren
Abschnitt betitelt „Lösung 4: Das Crate hinzufügen oder das Modul deklarieren“Nimm diese Lösung, wenn die Beschriftung use of unresolved module or unlinked crate lautet. Der erste Teil des Pfads ist ein Crate oder ein Modul, das Rust nicht kennt:
error[E0433]: cannot find module or crate `rand` in this scope --> src/main.rs:4:19 |4 | let mut rng = rand::rng(); | ^^^^ 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`Rust kennt kein Modul und kein Crate namens rand. Bei einem Crate von crates.io führst du in deinem Projektordner cargo add rand aus. Bei einem Modul der Standardbibliothek wie fs schlägt rustc stattdessen use std::fs; vor. Und bei deiner eigenen Datei, sagen wir src/inventory.rs, lautet die Hilfe to make use of source file src/inventory.rs, use `mod inventory` in this file to declare the module (deklariere das Modul mit mod inventory in dieser Datei):
src/├── main.rs inventory::count_items() ← braucht `mod inventory;` ganz oben└── inventory.rs pub fn count_items() -> u32 { 42 }Hier ist dasselbe Programm in einer Datei, mit direkt geschriebenem Modul, damit es im Playground läuft:
mod inventory { pub fn count_items() -> u32 { 42 }}
fn main() { println!("Artikel auf Lager: {}", inventory::count_items());}Ausgabe:
Artikel auf Lager: 42Mit einer eigenen Datei ändert sich nur eins: Aus mod inventory { ... } wird mod inventory;, und der Inhalt wandert nach src/inventory.rs.
Und was ist mit extern crate?
Abschnitt betitelt „Und was ist mit extern crate?“In altem Code siehst du vielleicht extern crate rand;. Seit der Edition 2018 brauchst du das nicht mehr: Sobald ein Crate in Cargo.toml steht, kannst du es direkt benutzen. extern crate behebt E0433 nicht. Ohne die Abhängigkeit verwandelt es den Fehler nur in E0463, can't find crate for rand (Crate rand nicht gefunden). Die echte Lösung ist cargo add.
Wo du ihn oft siehst
Abschnitt betitelt „Wo du ihn oft siehst“Vergleichen mit cmp. match a.cmp(&b) mit Ordering::Less-Zweigen ergibt E0433, und rustc schlägt zwei Importe vor: use std::cmp::Ordering; und use std::sync::atomic::Ordering;. Du willst std::cmp::Ordering; das atomare ist für Threads. Siehe Match.
Tests in einem mod tests-Block. Ein Testmodul ist ein Kindmodul. Es sieht deine Typen deshalb nicht, solange du sie nicht importierst. Inventory::new() in mod tests ergibt E0433 mit help: consider importing this struct und use crate::Inventory;. Lösung: Schreib use super::*; an den Anfang des Testmoduls. Siehe Testen in Rust.
Code aus Dokus oder Blogartikeln. Beispiele lassen ihre use-Zeilen oft weg. fs::read_to_string(...) schlägt fehl mit cannot find module or crate `fs` in this scope und der Hilfe use std::fs;. Lösung: Ergänze den Import, den rustc zeigt, oder schlag den Pfad des Elements auf seiner Doku-Seite nach.
Verwandte Fehler
Abschnitt betitelt „Verwandte Fehler“- E0432: dasselbe Problem in einer
use-Zeile,unresolved import(Import nicht gefunden). - E0425: Ein Wert oder eine Funktion wird nicht gefunden (ohne
::), etwa eine falsch geschriebene Variable. Aktuelles rustc benutzt E0425 auch für einen fehlenden Typ an einer Typ-Position, etwalet m: HashMap<&str, u32>; ältere Versionen nennen das E0412. Dieselbeuse-Zeile behebt es. - E0599: Der Typ wurde gefunden, aber die Methode oder Variante nach dem
::gibt es nicht, etwaLight::Blue. - E0463:
can't find crate, beiextern crateohne die Abhängigkeit. - Alle Compilerfehler: die vollständige Liste der Fehlerseiten.
Kurzer Check
Abschnitt betitelt „Kurzer Check“Kurzer Check
1. Warum ergibt HashSet::new() den Fehler E0433, während Vec::new() ohne Import funktioniert?
2. rustc schlägt für dein match a.cmp(&b) sowohl use std::cmp::Ordering; als auch use std::sync::atomic::Ordering; vor. Welchen nimmst du?
3. rand::rng() ergibt E0433 mit der Beschriftung „use of unresolved module or unlinked crate“. Was behebt den Fehler?
Punkte: 0 / 3
Weiterlesen
Abschnitt betitelt „Weiterlesen“- E0433 – Rust error codes index (auf Englisch): die offizielle Erklärung, mit dem Fall des nicht deklarierten Typs und dem des nicht eingebundenen Crates.
- Pfade in den Gültigkeitsbereich bringen mit dem Schlüsselwort use – Das Rust-Buch: wie
usefunktioniert und warum man Typen wieHashMapganz normal importiert. - Mit Pfaden auf ein Element im Modulbaum verweisen – Das Rust-Buch: volle Pfade,
crate::undsuper::. std::prelude– standard library docs (auf Englisch): die genaue Liste der Namen, die ohneusesichtbar sind.- Path and module changes in Rust 2018 – Edition Guide (auf Englisch): warum
extern cratenicht mehr nötig ist.