Prelude in Rust

In Rust, a “prelude” is a collection of commonly used types, functions, and macros that are automatically imported into every Rust program or module. This feature is designed to simplify the development process by providing easy access to essential functionalities without the need for explicit import statements. The prelude helps in writing more concise and cleaner code by reducing boilerplate and ensuring that frequently used items are readily available.

Overview

The concept of a prelude in Rust is implemented through re-exports, which allow symbols from another module or crate to be exported. This mechanism helps avoid the need to import individual symbols manually, reducing the risk of missing imports and simplifying code usage. Many libraries in Rust provide a prelude module to prevent namespace pollution, and users can import all symbols from the prelude using wildcard syntax.

For example, the standard library prelude includes items such as Vec and Result::Ok(), which are automatically available in every Rust program. This automatic importation is particularly beneficial for new Rust programmers, as it reduces the need to remember and write out numerous import statements for commonly used functionalities.

Creating and Using a Prelude

To create a prelude in a Rust library, you can define a module called prelude that exports all your most useful structs and functions. Here is an example of how a library might be structured with a prelude:

$ tree
.
├── Cargo.lock
├── Cargo.toml
└── src
    ├── a.rs
    ├── b.rs
    ├── lib.rs
    └── prelude.rs

1 directory, 6 files

In this setup, the prelude.rs file might contain:

pub use crate::a::InnerA;
pub use crate::b::InnerB;
pub use crate::TopLevelStruct;

This code re-exports all the structs from your crate in one place. A user of this crate can then import these structs using the wildcard use syntax:

use mylib::prelude::*;

This syntax imports everything exported from the top-level module of the mylib crate, making InnerA, InnerB, and TopLevelStruct available in the user’s scope.

Disabling the Prelude

There might be scenarios where a developer wants to disable the automatic import feature of the prelude. This can be achieved by using the attribute #![no_implicit_prelude]. When the prelude is disabled, the programmer must manually import all the standard library items they wish to use, which can make the code more verbose. Here is an example:

#![no_implicit_prelude]
fn main() {
    let my_vec = vec![8, 9, 10];
    let my_string = String::from("This won't work");
    println!("{my_vec:?}, {my_string}");
}

In this example, without explicit imports, the code will not compile, demonstrating the necessity of the prelude for concise and functional Rust code.

Prelude and Macro Expansion

The prelude also plays a role in macro expansion. When macros are expanded, the prelude ensures that necessary traits and types are available, which can simplify the expanded code. For instance, in the expanded code of a macro, you might see the use of prelude items without explicit imports.

Here is an example of prelude usage in macro expansion:

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;

struct Example;

impl Example {
    fn hello_world(&self) {
        {
            ::std::io::_print(
                format_args!("Hello, World\n")
            );
        }
    }
}

In this example, the prelude is imported using the #[prelude_import] attribute, which brings in the standard library’s prelude items. This allows the Example struct to use functionalities like println! without needing additional imports.

Conclusion

The prelude in Rust is a powerful feature that simplifies code by automatically importing commonly used traits and types. It plays a crucial role in both regular code and macro-expanded code, ensuring that essential functionalities are readily available without cluttering the code with numerous import statements. This feature enhances productivity and reduces boilerplate, making Rust programming more efficient and accessible.

Book TitleUsage of PreludeTechnical DepthConnections to Other ConceptsExamples UsedPractical Application
Idiomatic RustDiscusses prelude as a collection of useful types, functions, and macros for import, implemented through re-exports to simplify code usage. moreExplains re-exports and wildcard syntax for importing all symbols, reducing namespace pollution. moreConnects prelude to module and crate management, showing how it prevents missing imports. moreProvides a detailed example of creating and using a prelude in a library with modules a and b. moreHighlights the flexibility of using aliases and re-exports to tailor the prelude for library users. more
Learn Rust in a Month of LunchesDescribes prelude as a collection of standard library items automatically imported into every Rust program. moreDiscusses the #![no_implicit_prelude] attribute to disable automatic imports, making code more verbose. moreLinks prelude to the standard library, emphasizing its role in reducing boilerplate code. moreProvides an example of disabling the prelude, showing the necessity of explicit imports. moreHighlights the benefit of prelude for new programmers by simplifying the import process. more
Write Powerful Rust MacrosDefines prelude as a collection of items automatically imported into every module, simplifying development. moreExplores the role of prelude in macro expansion, ensuring necessary traits and types are available. moreConnects prelude to Rust’s module system and macro system, showing its integration in code expansion. moreDemonstrates prelude usage in a Rust program with macro expansion examples. moreEmphasizes prelude’s role in reducing import clutter and enhancing code readability. more

FAQ (Frequently asked questions)

What items can you use without explicit imports in Rust due to the prelude?

sitemap

Unable to load book!

The book could not be loaded.

(try again in a couple of minutes)

manning.com homepage
test yourself with a liveTest