Entry Points
Define the Entrypoint of your Application with the Main Function |
Define the Entrypoint of your Asynchronous Application |
Define the Entry Point of your Application with the Main Function
In Rust, the main function is special. It serves as the mandatory entry point for every executable program. The following is the most basic form of a main function:
// `main` takes no parameters and, in this case, // implicitly returns the "unit type" (), // similar to 'void' in C/C++/Java. fn main() { println!("Hello, world!"); }
It's typically found in the src/main.rs
file of a binary crate project. Note that library crates don't need one.
You can also have the main
function return a Result<(), E>
(where E
is a type that implements the std::error::Error
trait).
use std::fs::File; /// Example of a `main` function returning a `Result`, /// in this case a specialized `Result` type for I/O operations. fn main() -> std::io::Result<()> { let _f = File::open("non_existent_file.txt")?; // The ? operator returns early, if there is an error. println!("File opened successfully (this won't print)."); // Would return `Ok(())` on success. // The inner parens represent the unit type, i.e. the absence of a // meaningful return value. Ok(()) }
It is also common to return a Result
with a boxed error trait object, especially if multiple error types are possible:
use std::error::Error;
// ...
fn main() -> Result<(), Box<dyn Error>> {
// ...
}
More precisely, main
should return a type that implements std::process::Termination
. For example, you may return std::process::ExitCode
to provide a status code the current process can return to its parent.
Define the Entry Point of your Asynchronous Application
Rust also supports asynchronous main functions for writing concurrent applications using the async
/ await
syntax. To use async main
, you will need an async runtime like tokio
, often enabled via an attribute macro.
use anyhow::Result; /// This is an example of an async main function. /// /// It uses the `tokio::main` macro to create an async runtime. /// It returns a `Result` to allow for error handling. /// /// Add `tokio` with at least the "macros" and /// "rt-multi-thread" features to your `Cargo.toml`: /// /// ```toml /// tokio = { version = "1", features = ["full"] } /// ``` #[tokio::main] async fn main() -> Result<()> { println!("I'm async!"); // You can .await futures here. Ok(()) }
Related Topics
- Asynchronous.
- Functions.
- Package Layout.