Rust Programming
Rust Modules: A Comprehensive Guide to Packages and Best Practices
- Module In Rust program
- Visibility of The Items inside a Module in Rust program
- Nested Modules In Rust
- Crate and Package In Rust Program
- Rust Cargo Package Manager
- Dependency Management with Cargo in Rust Program
- Building and Running Project with Cargo in Rust Program
- Cargo Commands Useful in Rust
¶Module In Rust program
Modules in Rust Program help in rending a program into logical units for better readability and organisation.
Once a program turn larger, it is significant to divide it into multiple files or namespaces. Modules help in structuring to our program.
A module is a gathering of items: functions, structs and also other modules.
¶Defining a Module in Rust Program
The mod
keyword is used the define a module. The syntax of module is below:
// syntax of a module
mod module_name {
// code
}
Above, module_name
is the name of module
Please now, let’s define a module.
// a module named config
mod config {
// a function print inside of the module
fn print() {
println!("config!");
}
}
The above example, you make a module named config
using the mod
keyword.
Under the module you can define multiple items. Below, you have defined the print()
function.
¶Visibility of The Items inside a Module in Rust program
Inside Items a module can be private or public. By the default, a module is private. that means items inside the module cannot be appreciated outside of the module.
The pub
keyword can be used to given an item public assignation.
Now see an example-
mod config {
// items in modules by default have private visibility
fn select() {
println!("called config::select");
}
// use the `pub` keyword to override private visibility
pub fn print() {
println!("called config::print");
}
}
Above, you define a module named config
with the two functions select()
and print()
.
Supposing you compile the above program, you don’t feedback any output because you have not used the functions yet.
warning: function `select` is never used
--> src/lib.rs:3:8
|
3 | fn select() {
| ^^^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: function `print` is never used
--> src/lib.rs:8:12
|
8 | pub fn print() {
| ^^^^^
Now, let’s call the functions under the module.
mod config {
// items in modules by default have private visibility
fn select() {
println!("called config::select");
}
// use the `pub` keyword to override private visibility
pub fn print() {
println!("called config::print");
}
}
fn main() {
// public items inside module can be accessed outside the parent module
// call public print function from display module
config::print();
}
Output :
called display::print
Below, you call the public function print()
inside of config
module using the syntax config::print()
. The ::
operator is used to individual the module name and the item to call inside the module.
Still, private items inside of the module are not get-at-able outside the module. Suppose you call the private function select()
inside the config
module, you can get a compilation error.
mod config {
// items in modules by default have private visibility
fn select() {
println!("called config::select");
}
// use the `pub` keyword to override private visibility
pub fn print() {
println!("called config::print");
}
}
fn main() {
// private items inside module cannot be accessed outside the parent module
// calling private select function inside config module will cause a compilation error
display::select();
}
Error:
error[E0603]: function `select` is private
--> src/main.rs:16:14
|
16 | display::select();
| ^^^^^^ private function
Above error mentions that the function
select is private
. this, visibility of the items inside a module is an important design discretion.
¶Example: Using Module in Rust Program
mod player {
// private function
fn focus() {
println!("called player::focus");
}
// public function
pub fn shift() {
println!("called player::shift");
}
// public function
pub fn jump() {
// call private function focus and shift inside the module
focus();
shift();
println!("called player::jump");
}
}
fn main() {
// call public function jump from player module
player::jump();
}
Output :
called player::focus
called player::shift
called player::jump
Below, we identify multiple functions inside the player
module. Note that we are capable to call the private function focus()
in other function jump()
inside the same module.
¶Nested Modules In Rust
A module can be defined inside other module. Now This is known as module nesting.
Now see an example-
// nested module
pub mod player {
pub mod sprite {
pub fn create() {
println!("called player::sprite::create");
}
}
}
fn main() {
// call public function create from sprite module which is inside player module
player::sprite::create();
}
Output :
called player::sprite::create
Above, you have a sprite
module shelter within the player
module.
You define a public function create()
inside of the sprite
module what is called using player::sprite::create()
outside the module in the main()
function.
¶Keyword use in Rust Program
You can use the use
keyword to get items inside a module into the present scope. The use
keyword assistance us extract writing out the full module path to call functions.
Now let’s rewrite our nested module example by help of the use
keyword.
// nested module
pub mod player {
pub mod sprite {
pub fn create() {
println!("called player::sprite::create");
}
}
}
// bring the create function into scope
use player::sprite::create;
fn main() {
// call public function directly
create();
}
Output :
called player::sprite::create
Above, you use the use
keyword to get the create()
function into the present scope from the sprite
module which is the inside the player module. It’s allow us to call the create()
function presently, without having to fully determine the name as player::sprite::create()
.
¶Crate and Package In Rust Program
A crate can contain one or more than Rust modules, which in turn can comprise code, for example functions, types, and constants.
A crate is of two types:-
- Binary crate
- Library crate
A binary crate is a Rust program that compiles to an executable or multiplex executables and has a main()
function for every executable.
A library crate doesn’t compose to an executable and doesn’t have a main()
function. A library crate usually defines a apportion functionality that can be used in multiple projects
¶Creating a Package in Rust Program
You can use cargo to create a package. A package comprise one or more crates that take measures a set of functionality.
For create a binary package, you can use the cargo
command in the terminal.
$ cargo new hello_world --bin
Output :
Created binary (application) `hello_world` package
You make a binary package hello_world
using cargo
and the --bin
option. It is the default cargo conduct.
Now let’s look at the object of the hello_world
package.
hello_world
├── Cargo.toml
└── src
└── main.rs
Below,
-
hello_world_lib
is the package prescriptive -
Cargo.toml
is a file which comprise metadata about the crate, for example its name, version, and dependencies -
src/lib.rs
is crate root and comprise the source code of the library package
A package can comprise src/main.rs
also src/lib.rs.
In this case, it has been two crates: a binary and a library, both of with the same name as the package. Now for a example-
hello_world
├── Cargo.toml
└── src
└── lib.rs
└── main.rs
Note: Cargo by symposium passes the crate root files to the Rust Program compiler to build the library or binary.
¶Rust Cargo Package Manager
Cargo is the Rust Program package manager. It appears pre-installed with Rust and can be used to package dependency, manage them as well as construct and give away our own packages/libraries.
¶The Features of Cargo in Rust Program
Cargo is a order line tool for Rust which comes with this features:
- Dependency management In Rust
Cargo does it easy to manage the dependencies of your project, together with adding, updating, and removing dependencies. In Rust
- Building and packaging In Rust
Cargo can do automatically construct and package your Rust projects, making binary or library code that can be apportion with others.
- Document generation In Rust
Cargo can do automatically produce documentation for your code, creating it easier for several developers to understand and use our library.
- Download crates In Rust
Cargo can download and install library from crates.io, that is a central assortment for Rust crates.
- Run a binary or tests In Rust
Cargo can construct our source code, move the executable binary and also run our tests.
¶Dependency Management with Cargo in Rust Program
One of the elementary features of cargo is that it can download, conduct external libraries.
Beginning by creating a Rust project using cargo-
$ cargo new hello_world
Now,
Cargo.toml
file in the original of our project directory hello_world
is used to conduct the dependencies.
If we want to use the “rand” make, we add the following line to the [dependencies]
article of the Cargo.toml
.
[package]
name = "hello_world"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rand = "0.8.5"
- After, we’ll need to import the make in our
src/main.rs
Rust file. We can do it’s by usingextern crate <crate_name>
line at the head of the file.
extern crate rand;
- Now, we can use the “rand” make to produce a random number between 1 and 6. The
use
keyword is used to here to import items (such as functions, types, and constants) from the “rand” crate in the present scope.
extern crate rand;
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
// simulate rolling a die
println!("roll = {}", rng.gen_range(1..=6));
}
# Output: roll = 5
¶Building and Running Project with Cargo in Rust Program
You can use cargo to install, construct and run our hello_world
project with the “rand” crate. Now see how below-
Build in the project
$ cargo build
Output:
Compiling libc v0.2.139
Compiling cfg-if v1.0.0
Compiling ppv-lite86 v0.2.17
Compiling getrandom v0.2.8
Compiling rand_core v0.6.4
Compiling rand_chacha v0.3.1
Compiling rand v0.8.5
Compiling hello_world v0.1.0 (/experiments/rust-practice/hello_world)
Finished dev [unoptimized + debuginfo] target(s) in 2.57s
The cargo build
command at first installs any crates that’s in use inside the src/
directory and then proceeds to compose the project.
Run the project In Rust
$ cargo run
Output :
Finished dev [unoptimized + debuginfo] target(s) in 0.05s
Running `target/debug/hello_world`
roll = 5
¶Cargo Commands Useful in Rust
Cargo can do a cluster of Iterative tasks for us. Here are some of the same used cargo commands.
Rust Error Troubleshooting Comprehensive Guide to Memory Management
Advanced Rust Topics: Dive Deeper into the Language's Capabilities
All Tutorials in this playlist
Popular Tutorials
Categories
-
Artificial Intelligence (AI)
11
-
Bash Scripting
1
-
Bootstrap CSS
0
-
C Programming
14
-
C#
0
-
ChatGPT
1
-
Code Editor
2
-
Computer Engineering
3
-
CSS
28
-
Data Structure and Algorithm
18
-
Design Pattern in PHP
2
-
Design Patterns - Clean Code
1
-
E-Book
1
-
Git Commands
1
-
HTML
19
-
Interview Prepration
2
-
Java Programming
0
-
JavaScript
12
-
Laravel PHP Framework
37
-
Mysql
1
-
Node JS
1
-
Online Business
0
-
PHP
28
-
Programming
8
-
Python
12
-
React Js
19
-
React Native
1
-
Redux
2
-
Rust Programming
15
-
SEO - Search Engine Optimization
1
-
Tailwind CSS
1
-
Typescript
10
-
Uncategorized
0
-
Vue JS
1
-
Windows Operating system
1
-
Woocommerce
1
-
WordPress Development
2
Tags
- Artificial Intelligence (AI)
- Bash Scripting
- Business
- C
- C Programming
- C-sharp programming
- C++
- Code Editor
- Computer Engineering
- CSS
- Data Structure and Algorithm
- Database
- Design pattern
- Express JS
- git
- Git Commands
- github
- HTML
- Java
- JavaScript
- Laravel
- Mathematics
- MongoDB
- Mysql
- Node JS
- PHP
- Programming
- Python
- React Js
- Redux
- Rust Programming Language
- SEO
- TypeScript
- Vue JS
- Windows terminal
- Woocommerce
- WordPress
- WordPress Plugin Development