• rust组织结构


    一 、crate

    crate称为箱。
    crate有两种形式:二进制箱(binary crate)和库箱(library crate)。
    二进制箱必须有一个 main 函数,可以编译为可执行程序。
    库箱并没有 main 函数,它们也不会编译为可执行程序,它们只是提供一些函数供其他项目使用。

    crate root叫箱的根,是一个源文件,Rust编译器以它为起始点,构建你的crate。

    二、package

    package称为包。包就是一个工程项目,包必须有一个Cargo.toml文件。
    一个包至少包含一个箱,这些箱最多包含一个库箱,但可以包含任意数量的二进制箱。
    使用cargo new命令创建包。包名就是目录名。
    如果使用cargo new proj创建包,src目录下会默认生成一个main.rs源文件。
    如果使用cargo new --lib proj命令创建包,src目录下会默认生成一个lib.rs源文件。
    Cargo约定:
    src/main.rs是一个二进制箱的根。此箱名与包名相同。
    src/lib.rs是一个库箱的根。此箱名与包名相同。
    如果包只有src/main.rs文件,意味着包只含有一个二进制箱。此箱名与包名相同。
    如果一个包同时含有 src/main.rs和src/lib.rs,则它包含两个箱:一个二进制箱和一个库箱,且名字都与包相同。
    通过将文件放在src/bin目录下,一个包可以拥有多个二进制箱:src/bin下的每个文件都会编译成一个独立的二进制箱。此目录下的箱名与包名不同,而是与文件名相同。

    三、模块

    rust模块就是命名空间。

    (一)声明模块
    使用mod关键字来声明模块。

    mod hello {
         pub fn say_hello() {
             println!("hello world");
         }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    模块内的项默认是private,外部不可见,如果要外部可见需要加pub

    模块可以嵌套,形成模块树(module tree)

    mod nation {
         mod government {
             fn govern() {}
         }
         mod congress {
             fn legislate() {}
         }
         mod court {
             fn judicial() {}
         }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    每个箱都是一个模块树。src/main.rs 和 src/lib.rs 叫做箱根,是因为这两个文件为模块树创建了一个名为 crate 的根模块。

    crate
    └──nation
             ├──government
             │     └──govern
             ├──congress
             │     └──legislate
             └──court
                     └──judicial
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    (二)使用模块
    1.模块的路径
    如何在模块树中找到一个项的位置,我们使用路径,就像在文件系统使用路径一样。为了调用一个函数,我们需要知道它的路径。
    路径有两种形式:
    绝对路径(absolute path)是以箱根开头的全路径:引用外部箱代码,是以箱名开头的绝对路径;引用当前箱代码,则以crate开头。
    相对路径(relative path)从当前所在模块开始,以 self、super 或当前模块的标识符开头。
    (1)路径以双冒号(::)为分割符
    例如:

    mod front_of_house {
         pub mod hosting {
             pub fn add_to_waitlist() {}
         }
    }
    pub fn eat_at_restaurant() {
         // 绝对路径
         crate::front_of_house::hosting::add_to_waitlist();
         // 相对路径
         front_of_house::hosting::add_to_waitlist();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    (2)使用以 super 开头的相对路径

    fn deliver_order() {}
    mod back_of_house {
         fn fix_incorrect_order() {
             cook_order();
             super::deliver_order();
         }
         fn cook_order() {}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    (3)使用外部箱
    必须先添加依赖。在Cargo.toml中添加外部箱所在的包
    比如,

    [dependencies]
    rand = "0.8.5"
    
    • 1
    • 2

    Cargo要从 crates.io 下载 rand 和其依赖。
    这样就可以使用绝对路径使用外部箱了

    use rand::Rng;
    fn main() {
        let secret_number = rand::thread_rng().gen_range(1..101);
    }
    
    • 1
    • 2
    • 3
    • 4

    (4)std标准库
    std也是外部箱。因为标准库随Rust语言一同分发,无需修改 Cargo.toml 来引入 std
    比如,

    let mut guess = String::new();
    std::io::stdin().read_line(&mut guess).expect("failed readline");
    
    • 1
    • 2

    2.use语句
    无论是使用绝对路径还是相对路径都不便,我们可以使用 use 关键字创建一个短路径。

    (1)use关键字将模块标识符引入当前作用域:
    实例

    mod nation {
        pub mod government {
            pub fn govern() {}
        }
    }
    use crate::nation::government::govern;
    fn main() {
        govern();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    use关键字把govern标识符导入到了当前的模块下,可以直接使用。

    (2)可以使用use as为标识符添加别名:
    实例

    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();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    这里有两个govern函数,一个是nation下的,一个是government下的,我们用as将nation下的取别名nation_govern。两个名称可以同时使用。

    (3)use关键字可以与pub关键字配合使用:
    实例

    mod nation {
        pub mod government {
            pub fn govern() {}
        }
        pub use government::govern;
    }
    fn main() {
        nation::govern();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    (4)使用大括号引入相同模块的多个子模块,可以显著减少 use 语句的数量
    比如,

    use std::{cmp::Ordering, io};
    
    • 1

    (5)使用通配符*引入所有子模块
    例子

    use std::collections::*;
    
    • 1

    将 std::collections 中所有公有项引入当前作用域

    (三)将模块分割进不同文件
    到目前为止,都是在一个文件中定义多个模块。当模块变得更大时,你可能想要将它们移动到单独的文件中。
    例如,

    文件名: src/lib.rs
    mod front_of_house;	//声明front_of_house模块,其内容将位于src/front_of_house.rs
    pub use crate::front_of_house::hosting;
    pub fn eat_at_restaurant() {
         hosting::add_to_waitlist();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    文件名: src/front_of_house.rs
    pub mod hosting {
         pub fn add_to_waitlist() {}
    }
    
    • 1
    • 2
    • 3
    • 4

    在src/front_of_house.rs中定义front_of_house模块
    在mod front_of_house后使用分号,而不是代码块,表示在其他文件中定义模块。Rust会在与模块同名的文件中查找模块的代码。
    继续重构我们例子,将hosting模块也提取到其自己的文件中

    文件名: src/front_of_house.rs
    pub mod hosting;
    
    • 1
    • 2

    创建一个src/front_of_house目录,在src/front_of_house/hosting.rs文件中定义hosting模块:

    文件名: src/front_of_house/hosting.rs
    pub fn add_to_waitlist() {}
    
    • 1
    • 2
  • 相关阅读:
    产品推荐 | 基于Xilinx Kintex-7 FPGA K7 XC7K325T PCIeX8 四路光纤卡
    元宇宙006 | 你不了解的“养成系”人工智能就此诞生
    Redis最常见应用场景
    2022-11-01语音之家&火山音频的分享
    springcloudgateway Actuator API
    循环神经网络
    kail 搭建docker和vulhub漏洞环境
    leetcode做题笔记228. 汇总区间
    【组件封装】vue打字机效果和文字发光
    数据结构--》探索数据结构中的字符串结构与算法
  • 原文地址:https://blog.csdn.net/inxunxun/article/details/133546082