Rustのエラー E0432: unresolved import(インポートを解決できない)
E0432 は、use の行のどれかが、Rust の見つけられないものを指している、という意味のエラーです。クレートがまだ Cargo.toml に入っていないのかもしれませんし、パスに小さなつづりの間違いがあるのかもしれません。あるいは、ファイルはあるのに、それがモジュールだと Rust が知らないのかもしれません。見た目は怖そうですが、ほとんどの場合は1行直すだけで解決しますし、どの行が問題なのかもたいていコンパイラが教えてくれます。このシリーズのほかのエラーは、Rustのコンパイルエラー解説を見てください。
エラーメッセージ
Section titled “エラーメッセージ”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`「unresolved import rand」は「インポート rand を解決できない」という意味です。^^^^ の下のラベルは「解決できないモジュール、またはリンクされていないクレート rand を使っている」、help は「rand というクレートを使いたいなら、cargo add rand で Cargo.toml に追加してください」と言っています。
このエラーが出るのは、cargo new で作ったばかりで [dependencies] に何も書いていないプロジェクトの、次のプログラムです。
use rand::random_range;
fn main() { let roll = random_range(1..=6); println!("{roll}が出ました");}^^^^ の下に出る文言は、原因によって変わります。次のどれもが E0432 で、それぞれ下の別の直し方につながっています。
| ラベルに出る文言 | よくある原因 | 直し方 |
|---|---|---|
use of unresolved module or unlinked crate |
クレートが Cargo.toml にない、または mod の行がないファイル |
直し方1か直し方3 |
could not find `collection` in `std` |
パスの途中のつづりの間違い | 直し方2 |
no `Hashmap` in `collections` |
最後の名前のつづり(または大文字・小文字)の間違い | 直し方2 |
could not find `inventory` in the crate root |
宣言していないモジュールへの crate:: のパス |
直し方3 |
no external crate |
パスが間違ったモジュールから始まっている | 直し方4 |
エラーの意味
Section titled “エラーの意味”use の行は、ショートカットです。use rand::random_range; は「これから先、random_range と書いたら rand::random_range にあるもののことだよ」という意味です。このショートカットを作る前に、Rust はパスを1つずつたどる必要があります。まず rand を見つけ、次にその中の random_range を見つけます。
^^^^ の印が付いているのは、最初に失敗した部分です。ここでは先頭の rand なので、Rust は random_range を探すところまで進んでいません。help: の行は、その理由を推測しています。rand は crates.io のクレートなのに、このプロジェクトはまだそれを追加していない、ということです。
タクシーの運転手さんに「スプリングフェルド市のハーバー通り12番地」と住所を伝えたようなものです。市の名前が間違っていたら、運転手さんは通りを探し始めることさえできません。
Rust がこうする理由
Section titled “Rust がこうする理由”Rust はすべてのパスを、プログラムを実行するときではなく、コンパイルするときに解決します。「念のため」に何かを読み込んでおくことはありません。コードから見えるのは、3種類のものだけです。Cargo.toml に書いたクレート(と std)、mod で宣言したモジュール、そしてそれらの中のアイテムです。use の行がその外にあるものを指していたら、Rust は推測したりせず、その場で止まります。
これはよいことです。Python や JavaScript では、インポートのつづりの間違いは、その行が実際に実行されたときに初めてエラーになることがよくあります。本番環境でかもしれません。Rust では、そもそもビルドできません。それに、追加していないクレートがプログラムにこっそり紛れ込むことも絶対にありません。
2018 エディション以降、use のパスは次のどれかから始まります。クレートの名前(std、rand)、crate(自分のクレートのルート)、self(現在のモジュール)、super(親モジュール)、または現在のモジュールで宣言したモジュールです。詳しくはモジュールのレッスンで、依存クレートについてはCargoとクレートで説明しています。
直し方1:cargo add でクレートを追加する
Section titled “直し方1:cargo add でクレートを追加する”パスの最初の部分が rand、serde、regex のような crates.io のクレートで、help: の行に cargo add と書かれているときは、これを選びます。原因としてはこれがいちばん多く、ブログ記事からコードをコピーしたときは特によく起きます。Cargo.toml があるフォルダで、次のコマンドを実行しましょう。
cargo add randCargo が最新のバージョンを探して、Cargo.toml に1行追加してくれます。
[dependencies]rand = "0.10.3"これで同じコードがビルドできるようになります。下のプログラムは、出た目そのものではなく、範囲に入っているかどうかを表示するので、実行結果がいつも同じになります。
use rand::random_range;
fn main() { let roll = random_range(1..=6); println!("出た目は1から6の範囲: {}", (1..=6).contains(&roll));}実行結果:
出た目は1から6の範囲: trueここでつまずきやすい点が2つあります。1つ目は、ダッシュを含むクレート名は、コードの中ではアンダースコアになることです。cargo add tracing-subscriber で追加しても、書くときは use tracing_subscriber::... です。2つ目は、クレートがワークスペースの依存関係になっていても、それを使うパッケージの Cargo.toml にも書く必要があることです。
直し方2:パスのつづりを直す
Section titled “直し方2:パスのつづりを直す”ラベルに could not find `X` in `Y`(Y の中に X が見つからない)や no `X` in `Y`(Y に X はない)と出たときは、これを選びます。パスの途中か最後のどこかのつづりが間違っています。定番はこれです。
error[E0432]: unresolved import `std::collection` --> src/main.rs:1:10 |1 | use std::collection::HashMap; | ^^^^^^^^^^ could not find `collection` in `std`正しいモジュール名は、s の付いた collections です。名前は大文字と小文字も区別します。use std::collections::Hashmap; は no `Hashmap` in `collections` というエラーになり、rustc は help: a similar name exists in the module(モジュールに似た名前がある)と、正しいつづりを添えてくれます。直したインポートはこうです。
use std::collections::HashMap;
fn main() { let mut stock: HashMap<&str, u32> = HashMap::new(); stock.insert("apples", 12); println!("{:?}", stock.get("apples"));}実行結果:
Some(12)正しいパスがわからないときは、標準ライブラリのドキュメント(英語)で検索してみましょう。各アイテムのページのいちばん上に、フルパスが書かれています。この型についてはHashMapのページも見てください。
直し方3:mod でモジュールを宣言する
Section titled “直し方3:mod でモジュールを宣言する”src/inventory.rs のような新しいファイルを作ったのに、use inventory::... がそれを見つけられないときは、これを選びます。Rust では、親のファイルが宣言するまで、ファイルはモジュールになりません。プロジェクトはこうなっています。
src/├── main.rs use inventory::count_items; ← `mod inventory;` がない└── inventory.rs pub fn count_items() -> u32 { 42 }rustc は、何が足りないのかをはっきり教えてくれます。
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; |help は「ソースファイル src/inventory.rs を使うには、このファイルで mod inventory と書いてモジュールを宣言してください」という意味です。src/main.rs(そのモジュールがライブラリのものなら src/lib.rs)の先頭に mod inventory; を追加しましょう。代わりに use crate::inventory::count_items; と書いても解決しません。モジュールがまだ宣言されていないので、could not find `inventory` in the crate root(クレートのルートに inventory が見つからない)というエラーになります。
Playground ではすべてが1つのファイルに入るので、ここではモジュールを mod inventory { ... } とその場で書いています。別ファイルにしたときとまったく同じように動きます。
mod inventory { pub fn count_items() -> u32 { 42 }}
use inventory::count_items;
fn main() { println!("在庫の数: {}", count_items());}実行結果:
在庫の数: 42モジュールは、親の中で1回だけ宣言します。ほかのファイルからは use crate::inventory::... で使います。それを使うすべてのファイルに mod inventory; を書く必要はありません。
直し方4:パスを正しい場所から始める
Section titled “直し方4:パスを正しい場所から始める”インポートがモジュールの中にあって、使いたいアイテムが自分のクレートの別のモジュールにあるときは、これを選びます。ここでは、shop の中にある receipt が、shop::store_name を使おうとしています。
mod shop { pub fn store_name() -> &'static str { "Ferris Fruits" }
pub mod receipt { use store_name; // ❌ 探す場所が違う
pub fn header() -> String { format!("== {} ==", store_name()) } }}error[E0432]: unresolved import `store_name` --> src/main.rs:7:13 |7 | use store_name; // ❌ 探す場所が違う | ^^^^^^^^^^ no external crate `store_name`ラベルは「store_name という外部クレートはない」という意味です。use のパスの先頭に名前だけを書くと、「クレート、またはこのモジュールで宣言されたもの」という意味になります。store_name はそのどちらでもないので、Rust はその名前のクレートを探してしまいました。代わりに、どこから探し始めるのかを教えてあげましょう。
| 先頭に付けるもの | 探し始める場所 | 例 |
|---|---|---|
crate:: |
自分のクレートのルート(main.rs または lib.rs) |
use crate::shop::prices::price_of; |
super:: |
親モジュール | use super::store_name; |
self:: |
現在のモジュール | use self::lines::line; |
3つすべてを1つのプログラムで使うと、こうなります。
mod shop { pub fn store_name() -> &'static str { "Ferris Fruits" }
pub mod prices { pub fn price_of(item: &str) -> u32 { if item == "apple" { 3 } else { 5 } } }
pub mod receipt { use super::store_name; // 親モジュール:shop use crate::shop::prices::price_of; // クレートのルートから use self::layout::line; // このモジュールの子
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("apple");}実行結果:
== Ferris Fruits ==apple: 3ここでは use layout::line; と書いても動きます。layout は現在のモジュールで宣言されているからです。self:: は、それをはっきり書いているだけです。迷ったら、crate:: から始まるフルパスを書けば、クレートのどこからでも必ず使えます。rustc もよくこれを提案してくれます。help: a similar path exists(似たパスがある)のあとに、crate:: から始まるパスが表示されます。
よく出会う場面
Section titled “よく出会う場面”古いバージョンのクレート向けに書かれたコード。 多くのチュートリアルは rand 0.8 を使っています。rand 0.10 では、こうなります。
error[E0432]: unresolved import `rand::thread_rng` --> src/main.rs:1:5 |1 | use rand::thread_rng; | ^^^^^^^^^^^^^^^^ no `thread_rng` in the root「ルートに thread_rng はない」という意味です。直し方:Cargo.toml に書いたバージョンのドキュメントを docs.rs で確認します。ここでは新しい名前は rand::rng() です。乱数のページも見てください。
main.rs と lib.rs の両方があるパッケージ。 この2つは別々のクレートです。main.rs の中では crate:: はバイナリのほうを指すので、lib.rs に pub mod inventory; があっても、use crate::inventory::count_items; は could not find `inventory` in the crate root になります。直し方:パッケージ名を使って use shop_app::inventory::count_items; と書きます(ダッシュはアンダースコアに変えます)。
アイテムはあるけれど非公開。 これは E0432 ではなく、別のエラー E0603 です。
error[E0603]: function `count_items` is private --> src/main.rs:7:16 |7 | use inventory::count_items; | ^^^^^^^^^^^ private function「関数 count_items は非公開」という意味です。直し方:fn の前に pub を付けます(途中にある mod にも付けます。非公開のモジュールがあると module `prices` is private になるからです)。詳しくはモジュールを見てください。
関連するエラー
Section titled “関連するエラー”- E0433:コードの中のパス(
HashMap::new()やrand::rng()など)を解決できない。原因は同じですが、useの行ではない場所で起きます。 - E0425:値や関数が見つからない。同じ
useの行で直ることがよくあります。 - E0603:インポートするものは見つかったけれど、非公開になっている。
pubを付けます。 - E0463:
can't find crate(クレートが見つからない)。クレートがCargo.tomlにないのにextern crate rand;と書いたときに出ます。 - コンパイルエラーの一覧:エラー解説ページの全リストです。
理解度チェック
Section titled “理解度チェック”理解度チェック
1. 新しいプロジェクトに use serde::Serialize; をコピーしたら、クレート serde が unresolved または unlinked だという E0432 が出ました。直し方はどれですか?
2. src/billing.rs を作ったのに、main.rs の use billing::total; がエラーになります。何が足りないのですか?
3. mod shop { mod receipt { ... } } の中で、receipt が shop に直接定義された関数をインポートするにはどう書きますか?
スコア: 0 / 3
さらに詳しく
Section titled “さらに詳しく”- E0432 — Rust error codes index(英語):このエラーの公式の説明です。Rust 2018 でパスがどう変わったかも載っています。
- useキーワードでパスをスコープに持ち込む — The Rust Programming Language 日本語版:外部のパッケージやネストしたパスも含めて、
useのしくみを説明しています。 - モジュールツリーの要素を示すためのパス — The Rust Programming Language 日本語版:
crate::から始まる絶対パス、相対パス、superの使い方です。 - モジュールを複数のファイルに分割する — The Rust Programming Language 日本語版:モジュールを別ファイルにしたとき、
modをどこに書くかがわかります。 cargo add— The Cargo Book(英語):フィーチャーの指定も含めて、依存クレートを追加するためのすべてのオプションが載っています。