Lỗi Rust E0601: `main` function not found in crate (thiếu hàm main)
E0601 nghĩa là: Rust muốn build một chương trình, nhưng không tìm thấy chỗ bắt đầu của nó. Mọi chương trình Rust đều bắt đầu trong một hàm có tên chính xác là main, được viết ở cấp cao nhất của src/main.rs. Nếu nó bị thiếu, bị gõ sai, hoặc bị nhét vào trong một module, bạn sẽ gặp lỗi này. Lỗi này rất hay gặp khi bạn chép một đoạn code từ bài hướng dẫn hay tài liệu của một thư viện, và lúc nào cũng sửa nhanh. (Trang này thuộc loạt bài Giải thích các lỗi trình biên dịch Rust.)
Thông báo lỗi
Phần tiêu đề “Thông báo lỗi”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`Thông báo của trình biên dịch luôn bằng tiếng Anh: “main function not found in crate main” nghĩa là “không tìm thấy hàm main trong crate main”. Đây là chương trình gây ra lỗi đó (chú thích được giữ bằng tiếng Anh vì nó xuất hiện nguyên văn trong thông báo lỗi):
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Ý nghĩa
Phần tiêu đề “Ý nghĩa”Dấu ^ chỉ vào ngay cuối file, ngay sau dấu } cuối cùng. Trông thì lạ, nhưng hợp lý: rustc đã đọc hết file để tìm fn main, và tới cuối file mà không thấy. Không có dòng sai nào để chỉ vào; vấn đề là một dòng không hề tồn tại.
Tên crate trong thông báo phụ thuộc vào cách bạn build. Kết quả trên đến từ rustc src/main.rs, nên crate được đặt tên là main, theo tên file. Với cargo run, bạn sẽ thấy tên package trong Cargo.toml, ví dụ `main` function not found in crate `shop`. Cùng một lỗi, cùng cách sửa.
Giống như một kịch bản có những cảnh rất hay nhưng không có “Hồi 1, Cảnh 1”. Diễn viên đã sẵn sàng, nhưng chẳng ai biết vở diễn bắt đầu từ đâu.
Vì sao Rust làm vậy
Phần tiêu đề “Vì sao Rust làm vậy”Một binary Rust (chương trình bạn chạy được) cần một điểm vào (entry point) cố định. Khi bạn khởi động chương trình, hệ điều hành gọi main, và mọi thứ khác diễn ra vì main gọi tới chúng. Rust không đoán: không phải hàm đầu tiên trong file, không phải hàm tên start, không phải Main. Tên phải chính xác là main, viết thường hoàn toàn, ở cấp cao nhất của crate.
Code không tự chạy được như một chương trình, như một bộ hàm hỗ trợ cho code khác dùng, là một thư viện (library). Thư viện không có main và được viết trong src/lib.rs. E0601 thường có nghĩa là code vẫn ổn, chỉ là nằm sai loại crate. Xem Crate binary và library cùng nhau và Bắt đầu.
Cách sửa
Phần tiêu đề “Cách sửa”Cách sửa 1: Thêm hàm main (hoặc sửa chính tả của nó)
Phần tiêu đề “Cách sửa 1: Thêm hàm main (hoặc sửa chính tả của nó)”Phần lớn trường hợp, hãy chọn cách này: bạn đã chép các hàm từ đâu đó, hoặc bạn bắt đầu gõ các hàm hỗ trợ mà chưa viết main. Thêm fn main() và gọi code của bạn từ đó:
fn total(prices: &[u32]) -> u32 { prices.iter().sum()}
fn average(prices: &[u32]) -> u32 { total(prices) / prices.len() as u32}
fn main() { // ✅ chương trình bắt đầu từ đây let prices = [250, 199, 1200]; println!("tổng: {} xu", total(&prices)); println!("trung bình: {} xu", average(&prices));}Kết quả:
tổng: 1649 xutrung bình: 549 xuĐã có main rồi? Vậy hãy kiểm tra chính tả. fn Main(), fn mian() hay fn main_() đều gây ra đúng lỗi E0601 đó, vì với Rust chúng chỉ là những hàm khác. Tên phân biệt chữ hoa chữ thường, và nó phải là một hàm: fn main(), có cặp ngoặc tròn.
Cách sửa 2: Chuyển main ra khỏi module
Phần tiêu đề “Cách sửa 2: Chuyển main ra khỏi module”Chọn cách này khi thông báo nói the main function must be defined at the crate level (hàm main phải được định nghĩa ở cấp crate). Bạn có main, nhưng nó nằm trong một mod, nên thật ra nó là app::main, không phải điểm vào của chương trình:
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 definitionsChương trình đằng sau lỗi này:
mod app { pub fn main() { // ❌ inside a module, not at the top level println!("Starting the shop..."); }}Đặt main thật ở cấp cao nhất. Code trong module có thể giữ nguyên ở đó; hãy đặt cho nó một cái tên rõ hơn như run và gọi nó từ main:
mod app { pub fn run() { println!("Đang mở cửa hàng..."); }}
fn main() { // ✅ ở cấp cao nhất của src/main.rs app::run();}Kết quả:
Đang mở cửa hàng...Module ở file khác cũng vậy: một pub fn main() trong src/app.rs là app::main, không bao giờ là điểm vào. Xem Module.
Cách sửa 3: Biến nó thành thư viện, nếu nó không dùng để tự chạy
Phần tiêu đề “Cách sửa 3: Biến nó thành thư viện, nếu nó không dùng để tự chạy”Chọn cách này khi code là một bộ hàm hỗ trợ cho code khác dùng, chẳng có gì để “chạy”. Thư viện không có main. Tạo dự án với --lib:
cargo new --lib cart # creates src/lib.rs: a library, no main neededcargo new shop # creates src/main.rs with fn main(): a programLệnh thứ nhất tạo một thư viện (src/lib.rs, không cần main), lệnh thứ hai tạo một chương trình (src/main.rs có sẵn fn main()). Đặt các hàm hỗ trợ vào src/lib.rs, đánh dấu pub cho những gì code khác được dùng, và kiểm tra chúng bằng test thay vì 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); }}Với thư viện, hãy chạy cargo build hoặc cargo test. cargo run không dùng được ở đó; nó báo error: a bin target must be available for `cargo run`, cách Cargo nói rằng “package này không có chương trình nào”. Nếu bạn muốn có cả hai, hãy thêm một src/main.rs bên cạnh src/lib.rs. Nó dùng thư viện qua tên package:
fn main() { let sum = cart::total(&[250, 199, 1200]); println!("total: {} cents", sum);}Giờ cargo run in ra total: 1649 cents. Xem Crate binary và library cùng nhau và Kiểm thử.
Thường gặp ở đâu
Phần tiêu đề “Thường gặp ở đâu”Dán một đoạn code từ tài liệu hoặc bài hướng dẫn. Nhiều ví dụ chỉ cho thấy một hàm hoặc một struct, không phải cả chương trình. Dán vào src/main.rs, chúng gây ra E0601. Cách sửa: bọc những dòng thực hiện việc gì đó trong fn main() { ... }, còn hàm và struct thì để bên ngoài. (Rust Playground nhận ra việc thiếu main và đề nghị build code thay vì chạy, nên ở đó bạn thường không thấy lỗi này.)
Editor tô đỏ dòng cuối của main.rs. rust-analyzer chạy cargo check ở chế độ nền, nên bạn thấy E0601 ở dòng cuối trong lúc vẫn đang viết các hàm hỗ trợ. Không sao cả: dấu đỏ biến mất ngay khi bạn thêm fn main().
Chương trình phụ trong src/bin/. Mỗi file trong src/bin/, như src/bin/import.rs, là một chương trình riêng, và mỗi file cần fn main() của riêng nó. Cách sửa: thêm main vào file đó, hoặc chuyển code dùng chung vào src/lib.rs. Xem đường dẫn Cargo Targets ở cuối trang.
Lỗi liên quan
Phần tiêu đề “Lỗi liên quan”- E0425: cannot find value in this scope: một cái tên bị gõ sai ở chỗ khác trong chương trình, ví dụ gọi
totl(). - E0433: failed to resolve:
main.rskhông tìm thấy một module hoặc crate thư viện, ví dụcart::totalvới tên package sai. - E0603: item is private:
maintìm thấy hàm của thư viện, nhưng nó không phảipub. - E0463: can’t find crate: một crate bạn
usechưa có trongCargo.toml. - Tất cả lỗi trình biên dịch
Kiểm tra nhanh
Phần tiêu đề “Kiểm tra nhanh”Kiểm tra nhanh
1. src/main.rs của bạn có fn Main() { ... }. cargo run sẽ nói gì?
2. Bạn đang viết các hàm hỗ trợ cho code khác dùng, chẳng có gì để chạy. Cách tổ chức đúng là gì?
3. rustc nói “the main function must be defined at the crate level”. Có gì sai?
Điểm: 0 / 3
Đọc thêm
Phần tiêu đề “Đọc thêm”- E0601 — Rust error codes index (tiếng Anh): phần giải thích chính thức của lỗi này.
- Hello, World! — The Rust Book (tiếng Anh): hàm
mainđầu tiên của bạn, và vì sao mọi chương trình đều bắt đầu từ đó. - Packages and Crates — The Rust Book (tiếng Anh): crate binary so với crate thư viện,
src/main.rsso vớisrc/lib.rs. - Cargo Targets — The Cargo Book (tiếng Anh): thư viện, binary,
src/bin/và cách Cargo tìm ra từng cái. - Main functions — The Rust Reference (tiếng Anh): các quy tắc chính xác cho
main, kể cả nơi được phép định nghĩa nó.