Перейти к содержимому

Ошибка Rust E0601: `main` function not found in crate (нет функции main)

E0601 значит: Rust хотел собрать программу, но не нашёл, откуда она начинается. Каждая программа на Rust начинается с функции, которая называется ровно main и написана на верхнем уровне src/main.rs. Если её нет, в имени опечатка или она спрятана внутри модуля, получишь эту ошибку. Она очень часто встречается, когда копируешь фрагмент из учебника или документации библиотеки, и исправляется всегда быстро. (Эта страница входит в раздел Ошибки компилятора Rust с объяснениями.)

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 не найдена в крейте main». rustc предлагает добавить функцию main в src/main.rs.

Вот программа, которая её вызывает (комментарий // ❌ оставлен на английском, потому что rustc цитирует эту строку; он значит «конец файла, а fn 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

^ указывает на самый конец файла, сразу после последней }. Выглядит странно, но логика есть: rustc прочитал весь файл в поисках fn main и дошёл до конца, так и не найдя её. Указать на неправильную строку нельзя — проблема в строке, которой нет.

Имя крейта в сообщении зависит от того, как ты собираешь программу. Этот вывод получен через rustc src/main.rs, поэтому крейт называется main, по имени файла. С cargo run ты увидишь имя пакета из Cargo.toml, например `main` function not found in crate `shop`. Ошибка та же, исправления те же.

Это как сценарий пьесы с отличными сценами, но без «Действие 1, сцена 1». Актёры готовы, но никто не знает, где начинается спектакль.

Исполняемому крейту (binary, программе, которую ты запускаешь) нужна одна фиксированная точка входа. Когда ты запускаешь программу, операционная система вызывает main, а всё остальное происходит потому, что это вызывает main. Rust не гадает: не первая функция в файле, не функция start, не Main. Имя должно быть ровно main, строчными буквами, на верхнем уровне крейта.

Код, который сам по себе не программа, например набор вспомогательных функций для другого кода, — это библиотека (library). У библиотеки нет main, и она пишется в src/lib.rs. Часто E0601 значит, что код в порядке, просто он не в том виде крейта. Подробнее — в уроках Cargo и крейты и Начало работы.

Исправление 1: Добавь функцию main (или исправь её имя)

Заголовок раздела «Исправление 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(&prices));
println!("в среднем: {} коп.", average(&prices));
}

Вывод:

итого: 1649 коп.
в среднем: 549 коп.
▶ Попробуй сам

main уже есть? Тогда проверь, как она написана. fn Main(), fn mian() или fn main_() дают точно такую же E0601, потому что для Rust это просто другие функции. Имя чувствительно к регистру, и это должна быть функция: fn 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 definitions

rustc показывает найденную функцию 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!("Запускаем магазин...");
}
}
fn main() { // ✅ на верхнем уровне src/main.rs
app::run();
}

Вывод:

Запускаем магазин...
▶ Попробуй сам

То же самое с модулями в других файлах: pub fn main() в src/app.rs — это app::main, и точкой входа она никогда не будет. Подробнее — в уроке Модули.

Исправление 3: Сделай библиотеку, если код не должен запускаться сам

Заголовок раздела «Исправление 3: Сделай библиотеку, если код не должен запускаться сам»

Выбирай этот вариант, когда код — это набор вспомогательных функций для другого кода и «запускать» нечего. У библиотек нет main. Создай проект с --lib:

Terminal window
cargo new --lib cart # создаёт src/lib.rs: библиотека, main не нужна
cargo new shop # создаёт src/main.rs с fn main(): программа

Положи вспомогательные функции в src/lib.rs, отметь через pub то, чем может пользоваться другой код, и проверяй их тестами вместо cargo run:

src/lib.rs
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 говорит «в этом пакете нет программы». Если нужно и то и другое, добавь src/main.rs рядом с src/lib.rs. Он обращается к библиотеке по имени пакета:

src/main.rs
fn main() {
let sum = cart::total(&[250, 199, 1200]);
println!("total: {} cents", sum);
}

Теперь cargo run печатает total: 1649 cents. Подробнее — в уроках Cargo и крейты и Тестирование.

Вставка фрагмента из документации или учебника. Многие примеры показывают только функцию или struct, а не целую программу. Вставленные в src/main.rs, они дают E0601. Исправление: оберни строки, которые что-то делают, в fn main() { ... }, а функции и структуры оставь снаружи. (Rust Playground замечает, что main нет, и предлагает собрать код вместо запуска, так что там эту ошибку обычно не увидишь.)

Редактор подсвечивает последнюю строку main.rs красным. rust-analyzer в фоне запускает cargo check, поэтому ты видишь E0601 на последней строке, пока ещё пишешь вспомогательные функции. Это нормально: подсветка исчезнет, как только ты добавишь fn main().

Дополнительные программы в src/bin/. Каждый файл в src/bin/, например src/bin/import.rs, — отдельная программа, и каждой нужна своя fn main(). Исправление: добавь main в этот файл или перенеси общий код в src/lib.rs. См. ссылку про цели Cargo ниже.

Проверь себя

1. В твоём src/main.rs написано fn Main() { ... }. Что скажет cargo run?

2. Ты пишешь вспомогательные функции для другого кода, и запускать нечего. Как правильно всё устроить?

3. rustc пишет «the main function must be defined at the crate level». Что не так?

Результат: 0 / 3