Rust organization and management


Release date:2023-11-09 Update date:2023-11-10 Editor:admin View counts:217

Label:

Rust organization and management

It is difficult to go deep into any programming language if it cannot organize the code, and almost no software product is compiled from a source file.

All the programs in this tutorial so far have been written in one file, mainly to facilitate learning the syntax and concepts of the Rust language.

For a project, organizing code is very important.

There are three important organizational concepts in Rust: boxes, packages, and modules.

Box (Crate)

A “box” is a binary program file or library file that exists in a “package”.

The “box” is a tree structure, and its tree root is the program compiled by the source file compiled when the compiler starts running.

Note: a “binary program file” is not necessarily a “binary executable file”. It can only be determined to be a file that contains the target machine language, and the file format varies depending on the compilation environment.

Package

When we use Cargo to execute new command to create a Rust project, a Cargo.toml files. The essence of the project is a package, which must becomposed of a Cargo.toml file, which describes the basic information and dependencies of the package.

A package contains at most one library “box”, which can contain any numberof binary “boxes”, but at least one “box” (whether library or binary “box”).

When using cargo new after the command has created the package src directory will generate a main.rs source file, Cargo default this file is the root of the binary box, the compiled binary box will be the same as the package name.

Module

For a software engineering, we often organize according to the organization specification of the programming language used, and the main structure of the organization module is often tree. The main unit of Java organization function module is class, while the main way of JavaScript organization module is function .

The organizational units of these advanced languages can be contained in layers, just like the directory structure of the file system. The organizational unit in Rust is the module (Module).

mod nation {
    mod government {
        fn govern() {}
    }
    mod congress {
        fn legislate() {}
    }
    mod court {
        fn judicial() {}
    }
}

This is a procedure that describes a country under the rule of law: the nation includes the government, the congress and the court, which have executive, legislative and judicial functions, respectively. We can convert it into a tree structure:

nation
 ├── government
 │ └── govern
 ├── congress
 │ └── legislate
 └── court
   └── judicial

In the file system, the directory structure often uses a slash to indicate the location of the object in the path string, and the path separator in Rust is :: .

Paths are divided into absolute paths and relative paths. Absolute path from crate keyword begins to describe. Relative path from self or super keyword or an identifier begins to describe. For example:

crate::nation::government::govern();

Is a description. The govern absolute path of the function, and the relative path can be expressed as:

nation::government::govern();

Now you can try to define a similar module structure in a source program anduse the path in the main function.

If you do this, you will surely find something wrong with it: government modules and their functions are private, and you are not allowed to access them.

Access permission

There are two simple types of access in Rust: public and private.

By default, access to members in a module is private if no modifiers are added.

If you want to use public permissions, you need to use the pub keyword.

For private modules, they can only be accessed at their level or subordinatelocation, not from outside.

Example

mod nation {
    pub mod government {
        pub fn govern() {}
    }
    mod congress {
        pub fn legislate() {}
    }

    mod court {
        fn judicial() {
            super::congress::legislate();
        }
    }
}
fn main() {
    nation::government::govern();
}

This program can be compiled. Please pay attention to observation court in the module super access method.

If a structure is defined in the module, its fields are private by default, in addition to being private. So if you want to use the structure in the module and its fields, you need to pub declaration:

Example

mod back_of_house {
    pub struct Breakfast {
        pub toast: String,
        seasonal_fruit: String,
    }
    impl Breakfast {
        pub fn summer(toast: &str) -> Breakfast {
            Breakfast {
                toast: String::from(toast),
                seasonal_fruit: String::from("peaches"),
            }
        }
    }
}
pub fn eat_at_restaurant() {
    let mut meal = back_of_house::Breakfast::summer("Rye");
    meal.toast = String::from("Wheat");
    println!("I'd like {} toast please", meal.toast);
}
fn main() {
    eat_at_restaurant()
}

Running result:

I'd like Wheat toast please

Enumerated items of enumerated classes can contain fields, but do not have similar properties:

Example

mod SomeModule {
    pub enum Person {
        King {
            name: String
        },
        Quene
    }
}
fn main() {
    let person = SomeModule::Person::King{
        name: String::from("Blue")
    };
    match person {
        SomeModule::Person::King {name} => {
            println!("{}", name);
        }
        \_ => {}
    }
}

Running result:

Blue

Modules that are hard to find

Developers who have used Java tend to hate the outermost class block-its name is exactly the same as the file name, because it represents the file container, and although it is cumbersome, we have to write it again to emphasize that “this class is the class contained in the file.”

However, this has some advantages: at least it makes developers clearly aware of the existence of class wrappers, and can clearly describe the inheritance relationship of classes.

In Rust, a module is like a class wrapper in Java, but how to explain that you can write a main function at the beginning of a file?

The content of each Rust file is a module that is “hard to find”.

Let’s use two documents to reveal this:

main.rs file

// main.rs
mod second_module;
fn main() {
    println!("This is the main module.");
    println!("{}", second_module::message());
}

Second_module.rs file

// second_module.rs
pub fn message() -> String {
    String::from("This is the 2nd module.")
}

Running result:

This is the main module.
This is the 2nd module.

Use keyword

use keyword to introduce the module identifier into the current scope:

Example

mod nation {
    pub mod government {
        pub fn govern() {}
    }
}
use crate::nation::government::govern;
fn main() {
    govern();
}

This program can be compiled.

Because use keyword handle the govern identifier is imported into the current module and can be used directly.

This solves the problem that the local module path is too long.

Of course, there are cases where two identical names also need to be imported, and we can use the as keyword to add an alias to the identifier

Example

mod nation {
    pub mod government {
        pub fn govern() {}
    }
    pub fn govern() {}
}

use crate::nation::government::govern;
use crate::nation::govern as nation_govern;
fn main() {
    nation_govern();
    govern();
}

There are two here. govern function, one is nation , the next one is government , we’ll use as , set nation to give me an alias under nation_govern . Two names can be used simultaneously.

use keyword can be associated with the pub keyword in conjunction with:

Example

mod nation {
    pub mod government {
        pub fn govern() {}
    }
    pub use government::govern;
}
fn main() {
    nation::govern();
}

Reference standard library

Rust official Standard Library Dictionary: https://doc.rust-lang.org/stable/std/all.html

After learning the concepts in this chapter, we can easily import system libraries to facilitate the development of programs:

Example

use std::f64::consts::PI;
fn main() {
    println!("{}", (PI / 2.0).sin());
}

Running result:

1

All system library modules are imported by default, so you only need to use the use keyword simplifies the path and is easy to use.

Powered by TorCMS (https://github.com/bukun/TorCMS).