Rustのエラー E0601: `main` function not found in crate(main関数が見つからない)
E0601 は、Rust がプログラムをビルドしようとしたのに、どこから始まるのかが見つからなかった、という意味のエラーです。Rust のプログラムはどれも、src/main.rs のトップレベルに書かれた、ちょうど main という名前の関数から始まります。それがない、つづりが違う、モジュールの中に入っている、という場合にこのエラーが出ます。チュートリアルやライブラリのドキュメントからコードの一部をコピーしたときによく起こりますが、直すのはいつも簡単です。このシリーズのほかのエラーは、Rustのコンパイルエラー解説を見てください。
エラーメッセージ
Section titled “エラーメッセージ”error[E0601]: `main` function not found in crate `main` --> src/main.rs:7:2 |7 | } // ❌ end of the file, and no `fn main` anywhere | ^ consider adding a `main` function to `src/main.rs`「main function not found in crate main」は「クレート main に main 関数が見つからない」、「consider adding a main function to src/main.rs」は「src/main.rs に main 関数を追加してはどうか」という意味です。
このエラーが出るのは、次のプログラムです。
fn total(prices: &[u32]) -> u32 { prices.iter().sum()}
fn average(prices: &[u32]) -> u32 { total(prices) / prices.len() as u32} // ❌ end of the file, and no `fn main` anywhereコメントは「ファイルの終わり。fn main はどこにもない」という意味です(エラーになる例なので、コードはそのままにしています)。
エラーの意味
Section titled “エラーの意味”^ はファイルのいちばん最後、最後の } のすぐあとを指しています。変に見えますが、理由があります。rustc は fn main を探してファイル全体を読み、見つからないまま最後まで来てしまったのです。指すべき間違った行はありません。問題は、そこにない行なのです。
メッセージの中のクレート名は、ビルドのしかたによって変わります。この出力は rustc src/main.rs で出したものなので、クレートはファイル名から main と呼ばれています。cargo run なら、Cargo.toml のパッケージ名が表示されます。たとえば `main` function not found in crate `shop` のようにです。エラーも直し方も同じです。
すばらしい場面がそろっているのに、「第1幕 第1場」がない芝居の台本のようなものです。役者の準備はできていても、劇がどこから始まるのか誰にもわかりません。
Rust がこうする理由
Section titled “Rust がこうする理由”Rust のバイナリ(実行するプログラム)には、決まった入口が1つ必要です。プログラムを起動すると、OS が main を呼び、ほかのことはすべて main が呼ぶから起こります。Rust は推測しません。ファイルの最初の関数でも、start という名前の関数でも、Main でもだめです。名前はちょうど main、全部小文字で、クレートのトップレベルになければなりません。
それだけでは動くプログラムにならないコード、たとえばほかのコードから使われるヘルパーの集まりは、ライブラリです。ライブラリには main がなく、代わりに src/lib.rs に書きます。E0601 が出たとき、実はコードには問題がなく、クレートの種類が間違っているだけ、ということもよくあります。詳しくはバイナリクレートとライブラリクレートを一緒に使うとコードを理解しようを見てください。
直し方1:main 関数を追加する(またはつづりを直す)
Section titled “直し方1:main 関数を追加する(またはつづりを直す)”たいていはこれを選びます。どこかから関数をコピーしてきた、またはヘルパーを書き始めたけれど、まだ main を書いていない、という場合です。fn main() を追加して、そこから自分のコードを呼びましょう。
fn total(prices: &[u32]) -> u32 { prices.iter().sum()}
fn average(prices: &[u32]) -> u32 { total(prices) / prices.len() as u32}
fn main() { // ✅ プログラムはここから始まる let prices = [250, 199, 1200]; println!("total: {} cents", total(&prices)); println!("average: {} cents", average(&prices));}実行結果:
total: 1649 centsaverage: 549 centsもう main があるなら、つづりを確かめましょう。fn Main()、fn mian()、fn main_() は、どれもまったく同じ E0601 になります。Rust から見れば、ただの別の関数だからです。名前は大文字と小文字を区別しますし、かっこの付いた fn main() という関数でなければなりません。
直し方2:main をモジュールの外に出す
Section titled “直し方2:main をモジュールの外に出す”メッセージに the main function must be defined at the crate level(main 関数はクレートのレベルで定義しなければならない)とあるときは、これを選びます。main はあるのですが、mod の中にあるので、実際には app::main であって、プログラムの入口ではありません。
error[E0601]: `main` function not found in crate `main` --> src/main.rs:5:2 |5 | } | ^ the main function must be defined at the crate level (in `src/main.rs`) |note: here is a function named `main` --> src/main.rs:2:5 |2 | pub fn main() { // ❌ inside a module, not at the top level | ^^^^^^^^^^^^^ = note: you have one or more functions named `main` not defined at the crate level = help: consider moving the `main` function definitionsnote は「main という名前の関数はここにある」「クレートのレベルで定義されていない main という関数が1つ以上ある」、help は「main 関数の定義を移動してはどうか」という意味です。
このエラーが出るプログラムです(コメントは「モジュールの中で、トップレベルではない」という意味です)。
mod app { pub fn main() { // ❌ inside a module, not at the top level println!("Starting the shop..."); }}本物の main をトップレベルに置きましょう。モジュールの中のコードはそのままでかまいません。run のようなわかりやすい名前を付けて、main から呼びます。
mod app { pub fn run() { println!("Starting the shop..."); }}
fn main() { // ✅ src/main.rs のトップレベルにある app::run();}実行結果:
Starting the shop...別のファイルにあるモジュールでも同じです。src/app.rs の中の pub fn main() は app::main であって、決してプログラムの入口にはなりません。詳しくはモジュールを見てください。
直し方3:単独で動かすものでないなら、ライブラリにする
Section titled “直し方3:単独で動かすものでないなら、ライブラリにする”コードがほかのコードから使われるヘルパーの集まりで、「実行する」ものが何もないときは、これを選びます。ライブラリには main がありません。--lib を付けてプロジェクトを作りましょう。
cargo new --lib cart # src/lib.rs を作る:ライブラリなので main はいらないcargo new shop # fn main() のある src/main.rs を作る:プログラムヘルパーは src/lib.rs に書き、ほかのコードに使わせたいものに pub を付けます。確認は cargo run ではなくテストで行います。
pub fn total(prices: &[u32]) -> u32 { prices.iter().sum()}
#[cfg(test)]mod tests { use super::*;
#[test] fn adds_prices() { assert_eq!(total(&[3, 4]), 7); }}ライブラリには cargo build か cargo test を使います。ライブラリでは cargo run は動かず、error: a bin target must be available for `cargo run`(cargo run にはバイナリのターゲットが必要)と表示されます。Cargo なりの「このパッケージにはプログラムがない」という言い方です。両方欲しいなら、src/lib.rs の隣に src/main.rs を追加しましょう。ライブラリはパッケージ名で使います。
fn main() { let sum = cart::total(&[250, 199, 1200]); println!("total: {} cents", sum);}これで cargo run は total: 1649 cents と表示します。詳しくはバイナリクレートとライブラリクレートを一緒に使うとテストを見てください。
よく出会う場面
Section titled “よく出会う場面”ドキュメントやチュートリアルのコードを貼り付けたとき。 例の多くは、プログラム全体ではなく、関数や struct だけを載せています。それを src/main.rs に貼り付けると、E0601 になります。直し方:実際に何かをする行を fn main() { ... } で包み、関数や構造体はその外に置きます(Rust Playground は main がないことに気づいて、実行する代わりにビルドすることを提案してくれるので、そこではふつうこのエラーは見ません)。
エディタが main.rs の最後の行を赤くする。 rust-analyzer は裏で cargo check を実行しているので、まだヘルパーを書いている途中でも、最後の行に E0601 が表示されます。心配はいりません。fn main() を追加すれば、すぐに消えます。
src/bin/ の中の追加のプログラム。 src/bin/import.rs のような src/bin/ の中のファイルは、どれも別々のプログラムなので、それぞれに fn main() が必要です。直し方:そのファイルに main を追加するか、共通のコードを src/lib.rs に移します。下の Cargo Targets のリンクを見てください。
関連するエラー
Section titled “関連するエラー”- E0425:cannot find value in this scope。プログラムのどこか別の場所で名前のつづりを間違えた。たとえば
totl()を呼んだとき。 - E0433:failed to resolve。
main.rsからモジュールやライブラリクレートが見つからない。たとえば、パッケージ名を間違えてcart::totalと書いたとき。 - E0603:item is private。
mainからライブラリの関数は見つかったが、pubが付いていない。 - E0463:can’t find crate。
useしたクレートがCargo.tomlに入っていない。 - コンパイルエラーの一覧:エラー解説ページの全リストです。
理解度チェック
Section titled “理解度チェック”理解度チェック
1. src/main.rs に fn Main() { ... } があります。cargo run は何と言いますか?
2. ほかのコードから使うヘルパーを書いていて、実行するものは何もありません。正しい構成はどれですか?
3. rustc が「the main function must be defined at the crate level」と言いました。何が問題ですか?
スコア: 0 / 3
さらに詳しく
Section titled “さらに詳しく”- E0601 — Rust error codes index(英語):このエラーの公式の説明です。
- Hello, World! — The Rust Programming Language 日本語版:はじめての
main関数と、どのプログラムもそこから始まる理由です。 - パッケージとクレート — The Rust Programming Language 日本語版:バイナリクレートとライブラリクレート、
src/main.rsとsrc/lib.rsの違いです。 - Cargo Targets — The Cargo Book(英語):ライブラリ、バイナリ、
src/bin/と、Cargo がそれぞれをどう見つけるかです。 - Main functions — The Rust Reference(英語):
mainについての正確なルールです。どこに定義できるかも書かれています。