Rust编程-包、模块、单元包

Rust模块系统:

        包(Package):一个用于构建、测试并分享单元包的Cargo功能。

        单元包(crate): 一个用于生成库或可执行文件的树形模块结构。

        模块(module): 它们被用于控制文件结构、作用域及路径的私有性。

        路径(path):一种用于命名条目的方法,这些条目包括结构体、函数和模块等。

       总结:模块系统的作用主要是用来管理和组织代码。代码既可以作为公共接口部分供他人使用,也可以作为私有化实现细节,保留代码修改的权利。

包和单元包

        (可以类比前端工程):

                1. Cargo.toml类比package.json。Cargo.toml文件描述构建当前工程的单元包的信息,同时还有引用第三方依赖的信息。

                2. 包中单元包(二进制单元包和库单元包):

                        src/main.ts: 二进制单元包的根节点 ,且二进制单元包与包拥有相同的名称。在src/bin路径下添加源文件来创建出更多的二进制单元包

                        src/lib.rs:库单元包的根节点。和包拥有过相同的名称一个包中只能拥有最多一个库单元包。

                3. 理解二进制单元包和库单元包:二进制单元包是为了开发当前业务系统;库单元包类比开发可以通过npm安装的依赖组件。

包和单元包的规则:

1. 一个包中只能拥有最多一个库单元包。

2. 包可以拥有任意多个二进制单元包。

3. 包内必须存在至少一个单元包(库单元包或二进制单元包)。

        总结:

        1. 包可以类比前端工程

        2. 单元包分为二进制单元包和库单元包。二进制单元包就是开发当前业务系统;库单元包是为了开发组件库(类比npm组件)

模块、条目和路径:

    模块划分:

        模块将单元包内的代码按照可读性与易用性来进行分组。模块关键字mod

        模块包含条目,条目可以是函数、结构体、模块。可以控制条目的私有性和公有性(pub关键字)。

// src/lib.rs 库单元包,拥有和库相同的名称
// 将库单元包通过模块进行划分,模块中又可以包含函数(fn定义)、和子节点(hosting)
// front_of_house 称为 hosting的父节点
mod front_of_house{  
    mod hosting{
        fn add_to_waitlist(){

        }

        fn seat_at_table(){
            
        }
    }
}

来自《Rust权威指南》 

      模块,我们可以将相关的定义分到一组。src/main.rs 与src/lib.rs 被称作单元包的根节点,因为这两个文件的内容各自组成了一个名为crate的模块,并位于单元包模块结构的根部。这个模块结构也被称为模块树(module tree)

模块树的作用类比目录结构,这种设计主要作用还是为了方便查找代码所在位置,也能够避免命名冲突,因为两个相同名称的子节点在树的不同分支上。

        路径:

            路径的作用是用于查找模块里的条目

路径有两种形式:
• 使用单元包名字面量crate从根节点开始的绝对路径。
• 使用selfsuper或内部标识符从当前模块开始的相对路径。

绝对路径与相对路径都由至少一个标识符组成,标识符之间使用双冒号(::)分隔。

mod front_of_house{
    pub mod hosting{
        pub fn add_to_waitlist(){
        }
        fn seat_at_table(){
        }
    }

    mod seving{
        fn take_order(){}
        fn serve_order(){}
        fn take_payment(){}
    }
}

pub fn eat_at_restaurant(){
    
    // 绝对路径,以包名(crate关键字指向包名)开头
    crate::front_of_house::hosting::add_to_waitlist()
    
    // 使用相对路径,以模块开头
    front_of_house::hosting::add_to_waitlist();
}

crate 这里是字面量,表示当前库单元包的包名。

想要使用模块的函数,模块内的条目必须使用pub关键字修饰

大部分的Rust开发者会更倾向于使用绝对路径,因为我们往往会彼此独立地移动代码的定义与
调用代码。

总结:

        1. 模块的作用主要是功能相关的代码分组到一起

        2. 条目是模块的组成部分,包含变量、结构体、枚举、子节点等

        3. 路径是访问条目的路径。是条目在模块树的节点的路径。

路径的绝对和相对:

        绝对路径:

                关键字crate指向包名。路径是从包名开始,根模块的模块名和包名相同。

        相对路径:

                关键字super:父模块开始构造相对路径,类似于在文件系统中使用..语法。

fn serve_order(){

}

mod back_of_house{
    fn fix_incorrect_order(){
        cook_order();
        super::serve_order(); // super指向了上一层模块
    }

    fn cook_order(){}
}

pub、结构体和枚举:

        pub可以定义结构体的部分属性是pub的,没定义的默认是私有的

        pub 直接修饰枚举定义,枚举的所有变体都是公有的

pub、use:

        use将路径导入作用域

        借助use关键字来将路径引入作用域,并像使用本地条目一样来调用路径中的条目。

mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}
use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
    hosting::add_to_waitlist(); // 从hosting模块开始
    hosting::add_to_waitlist();
    hosting::add_to_waitlist();
}

        在单元包的根节点下添加use crate::front_of_house::hosting,就如同hosting模块被定义在根节点下一样。

         使用use来指定相对路径路径的开始处使用关键字self:(未来可能会去掉

use self::front_of_house::hosting;

       引入路径问题:

                惯用方式是use后面的路径到条目的父级路径

                use将结构体、枚举和其他条目引入作用域时,习惯于通过指定完整路径的方式引入

         as关键字

                可以解决use引入同名条目的时候,将名字修改为别名。

        pub use重导出名称

pub use crate::front_of_house::hosting; // pub use使一个名称可以在新作用域中被其他任意代码使
用

        Cargo.toml

                [dependencies] 表示外部依赖。需要手动写依赖和依赖的版本

[dependencies]
rand = "0.5.5"

        Cargo从crates.io上下载rand及相关的依赖包 

        不知道后面会不会出类似npm的依赖安装工具

        

use rand::Rng;
fn main() {
    let secret_number = rand::thread_rng().gen_range(1, 101);
}

        use 引入的是Rng trait。 因为rand::thread_rng() 函数是继承了Rng Trait,所以,必须要使用use引入下。(这里有点繁琐了,为什么不是直接引入rand

        标准库(std)已经被内置到了Rust语言中,不需要Cargo.toml文件中引入,但是需要use引入。

  use多分支引入:

use std::{cmp::Ordering, io};
use std::io::{self, Write}; // 表示引入io和io::Write

use使用通配符:

        

use std::collections::*;

定义在std::collections内的所有公共条目都导入当前作用域,然而这种使用方法存在弊端,就是不清楚该作用域都有哪些条目。

模块拆分到文件:

// src/lib.rs 

mod front_of_house; // 区别于模块定义,这里让rust去模块文件中查找条目

pub use crate::front_of_house::hosting;

pub fn eat_at_restaurant(){
    hosting::add_to_waitlist();
}


// src/front_of_house.rs

pub mod hosting{
    pub fn add_to_waitlist(){}
}

   关键是mod front_of_house; 拆分到不同文件的关键。新建的src/front_of_house.rs文件里的代码就只包含了子节点和子节点的函数。

  然后,创建名字为front_of_house的文件夹,在该文件夹下创建hosting.rs文件,将函数add_to_waitlist函数的定义放进去。这样就完成了模块拆分到不同的文件中。

   总结:

        模块拆分到文件,采用了类似文件目录的方法:文件(模块同名)用来存储其子节点的条目,或者通过mod +子节点名称方式告诉rust去查找子节点模块模块同名文件夹存储子节点的条目的文件

总结:

        文章引字《Rust权威指南》一书。通过整理让概念和知识点更加条理清晰。

        本章都是概念知识很简单,但是需要把知识点梳理清楚

  • 28
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值