Rust control scope and privateness
Concise and quick search of modules, paths and use keywords
Before starting a specific case, let’s take a look at some basic rules of the Rust module system:
Start with the crate root
The compiler will first be in the crate root (the default for the library crate issrc/
, for binary crate, the default issrc/
) find the code.
Declare module
In the crate root, you can usemod
A keyword declares a module, for example:
mod garden;
The compiler will look for it in the following locationsgarden
Module implementation:
- Written in braces (instead of semicolons)
- document
src/
- document
src/garden/
Declare submodules
Submodules can also be declared in non-crate root files, for examplesrc/
middle:
mod vegetables;
The compiler will look for it in the following places:
- Code in inline braces
- document
src/garden/
- document
src/garden/vegetables/
Code in the path access module
- Once the module is introduced into the crate, the code inside can be accessed through the path.
- For example, assuming
Asparagus
The type is defined insrc/garden/
, then its complete path is:
crate::garden::vegetables::Asparagus
Privacy and openness
- By default, the code in the module is private to the parent module.
- If you need to make the module or items visible to the outside, you need to use
pub
Decoration:
pub mod garden; pub fn some_function() { ... }
use
Keywords
To reduce duplicate input for long paths, it can be used within scopeuse
Keyword creation path alias:
use crate::garden::vegetables::Asparagus;
From then on, the current scope only needs to be usedAsparagus
This type can be referenced.
Practical Case: Building a Sample Project
Let's take a sample project to gain insight into the application of module systems.
Suppose we create a binary crate calledbackyard
, the directory structure is as follows:
backyard ├── ├── └── src ├── garden │ └── ├── └──
crate root: src/
- This is the entry file for the project.
- Here we will use
pub mod garden;
Tell the compiler tosrc/
Find ingarden
Definition of module.
Module implementation: src/
- In this file, you can continue to declare submodules, for example:
pub mod vegetables;
The compiler will automatically searchsrc/garden/
implementation in .
Submodule: src/garden/
- It can be defined here
vegetables
Specific structures, functions, etc. in the module. - This way of organizing files and modules makes the code structure very close to the file directory structure, making it easier for developers to understand and maintain projects.
Group-related code: Take the restaurant system as an example
Modules are not just to disperse code files, but more importantly, they help us logically group the relevant code and clarify their scope and disclosure.
Let’s take a restaurant system as an example to illustrate how to use modules to divide the front of house and back of house functions.
1. Create a project
Run the following command to create a new library crate:
cargo new restaurant --lib
2. Define the module structure
existsrc/
In, we can define the following module structure:
pub mod front_of_house { pub mod hosting { pub fn add_to_waitlist() { // Implementation details } fn seat_at_table() { // Only used internally } } pub mod serving { pub fn take_order() { // Implementation details } pub fn serve_order() { // Implementation details } pub fn take_payment() { // Implementation details } } }
As shown above:
-
front_of_house
Modules are disclosed to the public (pub mod
), indicating that the front desk part of the restaurant can be called externally. - Submodules under the front desk module
hosting
andserving
Also used separatelypub mod
Make a declaration, where some functions (e.g.seat_at_table
) Stay private and only for internal module calls.
3. Module tree schematic
The above code forms the following module tree:
crate └── front_of_house ├── hosting │ ├── add_to_waitlist │ └── seat_at_table └── serving ├── take_order ├── serve_order └── take_payment
This grouping method not only makes the code logic clear, but also the exposed interfaces are very clear.
4. Useuse
Keyword simplified calls
You can use the functions of the restaurant system in other modules or binary crateuse
To introduce modules:
use crate::front_of_house::hosting; fn eat_at_restaurant() { hosting::add_to_waitlist(); }
This greatly reduces the hassle of repeating long paths and makes the code easier to read.
Summarize
Rust's module system provides a powerful and flexible mechanism for the organization and access control of code:
Module declaration and file organization
- pass
mod
Keywords - We can spread the code into multiple files
- The compiler automatically searches for the corresponding module implementation according to the convention
Path anduse
Keywords
- Through the path, we can accurately locate the items in the module;
- and
use
Keywords help us simplify path references within local scopes and improve code readability.
Privacy and openness
- By default, the contents in the module are private
- use
pub
Keywords can selectively disclose the parts that need to be exposed - Ensure the encapsulation of internal implementation
Logical grouping and organization
- For example, in the example of a restaurant system, the modules of the front desk and the back desk are divided by the modules of the front desk and the back desk.
- Not only makes the code structure clearer, but also facilitates subsequent function expansion and maintenance
Mastering the knowledge of these module systems, you can easily manage complex code structures when building large projects and improve development efficiency.
Hopefully this blog will help you better understand the modules in Rust and their mechanisms for controlling scope and privacy, and start your modular programming journey in the world of Rust.
The above is personal experience. I hope you can give you a reference and I hope you can support me more.