• Rust 学习之 mod


    Rust 学习之 mod

    网上说,Rust 的学习曲线不像其他语言那样,用一句话描述就是:从入门到入门。这用在我身上很准确,我先后曾不止两次入门,每两次之间又都相隔数月,以至于经常需要翻阅 Rust 官方书 《Rust 编程语言》

    不过说真的,随着自学的逐步加深,会觉得越来越喜欢 Rust(可能是没有在实际项目中深入的使用导致),但既然很喜欢,那就借着这份热情,好好地了解“她”。

    从去年到现在,差不多一年左右,除了把官方书看完了,还利用碎片时间将范长春前辈的《深入浅出 Rust》看完。大部分是在地铁上看的,所以实践的不够,这篇记录 Rust mod 也是其中一篇笔记。

    在阅读该篇笔记之前,需要你先认真读完官方书的 mod 章节

    由于 Rust 提供了非常好用的工具链 —— cargo,用户只需简单的 cargo new pro_name 即可创建一个目录很规范的可执行程序的项目,用户做的只需将精力放在开发逻辑上,大大减少了心智负担。而这也能满足很多类型的中小项目。

    而在编写大型的项目时,又可以通过 Rust 的模块化支持来很好的实现。通过 Rust 模块的学习,我们可以看出,Rust 模块很强大并且不失灵活。例如:

    1.你可以在单个文件中编写多个模块。

    // src/notes/test_module/single_mod.rs
    pub mod single_mod {
        pub mod my_mod1 {
            pub fn mod1_func1() {
                println!("file:single_mod-single_mod-my_mod1-mod1_func1");
            }
        }
    
        pub fn func_0() {
            // 调用父级模块下的函数
            println!("调用父级模块下的函数:");
            super::level1_mod1::mod1_func1();
            // 调用同级下的模块下的函数
            println!("调用同级下的模块下的函数:");
            my_mod1::mod1_func1();
            println!("file:single_mod-single_mod-func_0");
        }
    }
    
    pub mod level1_mod1 {
        pub fn mod1_func1() {
            println!("file:single_mod-level1_mod1-mod1_func1");
        }
    }
    

    2.也可以将一个 rs 文件作为一个模块。将一个文件作为一个模块,也就意味着里面可能会有函数声明、类型声明、trait 声明等。

    // 函数声明
    pub fn one_file_func() {
        println!("file:one_file-one_file_func");
    }
    
    trait Human {
        fn speak();
    }
    
    // 类型声明
    #[derive(Debug)]
    pub struct Stu {
        id: i32,
        name: String,
        age: u8,
    }
    
    impl Human for Stu {
        fn speak() {
            println!("I speak Chinese.")
        }
    }
    
    impl Stu {
        pub fn new() -> Stu {
            Stu {
                id: 1,
                name: String::from("张太一"),
                age: 24,
            }
        }
    }
    

    3.在一个 crate 中你可以做到多个模块、子模块的嵌套。

    // src/notes/test_module/single_mod.rs
    pub mod single_mod {
        pub mod my_mod1 {
            pub fn mod1_func1() {
                println!("file:single_mod-single_mod-my_mod1-mod1_func1");
            }
        }
    
        pub fn func_0() {
            // 调用父级模块下的函数
            println!("调用父级模块下的函数:");
            super::level1_mod1::mod1_func1();
            // 调用同级下的模块下的函数
            println!("调用同级下的模块下的函数:");
            my_mod1::mod1_func1();
            println!("file:single_mod-single_mod-func_0");
        }
    }
    

    单文件多模块

    先说单个 rs 文件中的模块。在一个 rs 文件中,我们可以通过 mod 关键字新建很多个模块,例如 single_mod.rs 中的示例代码。
    这种比较适合小型的工具类的程序,不需要太多文件,就能在有限的文件中,拆分 module。局限性就是不适合代码多的项目,拆分不是很清晰。

    单仓库多模块

    这里的单仓库,本意是指在单个的 crate 中。前两天刚好看到了一个文章 —— Rust module 系统详解,这篇文章由浅入深的阐释了 crate 和 module 的联系。

    在一个 crate 中,我们可以声明很多个 module。这里我们以一个 Rust bin 程序作为示例,用 cargo new --bin crate_module 创建一个项目框架,使用 tree . 可查看其目录如下所示:

    .
    ├── Cargo.toml
    └── src
        └── main.rs
    
    1 directory, 2 files
    

    这个 crate 的根模块可以认为是从 src 目录开始,当我们要在 main.rs 中调用 user_service.rs 中的方法/函数时,需要先在 main.rs 文件中引入 —— mod services;,使用了这个语句后,Rust module 系统会有两个选择:

    • 1.在当前目录下寻找 services.rs 文件。因为一个 rs 文件可以看做一个 module
    • 2.在当前目录下寻找 services/mod.rs 文件。此时 services 可以看做是一个命名空间,它背后,可以有很多的 module(通过 mod.rs 文件管理)

    而在我们的“crate_module”例子中,恰好是第 2 种方式 —— 加载 services/mod.rs 文件。

    增加了 services 目录后的文件列表如下:

    .
    ├── Cargo.lock
    ├── Cargo.toml
    ├── src
    │   ├── main.rs
    │   └── services
    │       ├── mod.rs
    │       └── user_service.rs
    

    因此,在项目的 src 目录下,main.rs 中如果要引入一个 helper.rs 文件,我们只需在 main.rs 文件中这样做:mod helper;,这样在 main.rs 中就能使用 helper.rs 文件中导出的类型、函数等内容。

    mod helper;
    
    use helper::Helper;
    
    fn main() {
        let h1 = Helper::new();
        println!("{:?}", h1);
    }
    

    workspace

    上面一节所说的将许多的 module 分散在不同的目录、文件中,可以将项目拆分开,以写出更加抽象、可复用的代码。

    当随着项目开发的深入,业务的增长,代码越来越多,就会导致 crate 持续增大,我们可能会希望将其拆分成多个 crate,这有些类似于 web 开发中的微服务,将服务抽象进行抽象,拆分成不同的模块和类型,通过接口来进行调用。Rust 中 workspace 的概念就是类似的作用。

    在官方的 cargo 书上,对 workspace 也有比较详细的介绍

    更加详细的 workspace 实践,可以参考这里的实例

    其他

    reference

  • 相关阅读:
    经济危机下,自主创业已成为一种时代潮流?
    曾靖雯(帮别人名字作诗)
    四大内伤造就80后创业高失败率
    如何让创业的路不再崎岖
    叶莉(帮别人名字作诗)
    谁能够在萧条中生存?历史总是惊人相似的(转)
    哪种书最适合创业者阅读
    中西部崛起 关键是要激发普遍的创业热情
    每日英语:Dating in China Is a Largely Commercial Transaction
    每日英语:Poor Chinese Schools Tell Students: Bring Your Own Desks
  • 原文地址:https://www.cnblogs.com/ishenghuo/p/13539547.html
Copyright © 2020-2023  润新知