Rust基础知识10 - Package、Crate、Module

简介

  • 接上回

Rust 的模块系统的基本概念

Package、Crate、Module、Path:

顶层、Package 包,Cargo的特性,让你构建、测试、共享crate
第二层、Crate 单元包,一个模块数,它可以产生一个library 或可执行文件。
第三层、Module 模块,控制代码的组织、作用域、私有路径。
最后、Path 路径,为struct、function或module等项命名的方式。

Crate 相关

  • 包(package)创建规则:
1、一个包中至多只能包含一个库Crate。
2、包中可以包含任意多个二进制Crate。
3、包中至少包含一个 crate,无论是库的还是二进制的。
4、包中应该包含一个 Cargo.toml 配置文件,用来说明如何去构建这些 crate。
  • Package 的特点:
1、包含一个 Cargo.toml
2、默认的项目的 `binary crate` 的入口文件是 src/main.rs 
3、默认的库 `library crate` 的入口文件是 src/lib.rs 库名称与Package的名称相同。
4、所以一个package 既可以包含一个 `main.rs` 也可以包含 一个 `lib.rs`
5、文件放置 src/bin 下面,每个文件都是单独的binary crate

s

定义Module 来控制作用域和私有性

  • Module 在一个crate内,将代码进行分组。
  • 增加可读性,易于复用。
  • 控制项目(item)的私有性,通过public、private
  • 通过 mod 关键字创建module
  • module 是可嵌套的。
  • module 可以包含其他项(struct、enum、常量、trait、函数等)的定义

代码测试

  • 举一个例子比上面的文字更有意义:
pub mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist () -> u32 {
            println!("############ add_to_waitlist ############");
            555
        }
    }
    mod serving {
        pub fn take_order (){
            
            println!("RUN take_order");
        }
        pub fn serve_order (){
            println!("RUN serve_order");
        }
    }
}

路径 Path

  • 为了在Rust 的模块中找到某个条目,需要使用路径。
  • 路径的两种形式:
1、绝对路径,从 crate root 开始,使用crate 名或者字面值crate 
2、相对路径,从当前模块开始,使用self,super 或者当前模块的标识符号。
  • 路径至少由一个标识符组成,标识符之间使用::

使用pub 关键字

  • 默认上 Rust 中所有条目(函数,方法,struct,enum,模块,常量)默认是私有的
  • 父级模块无法访问子模块中的私有条目。
  • 子模块里可以使用所有祖先模块中的条目。
  • pub 放在 struct 前,struct 是公共的,但是struct 的字段默认是私有的。
  • pub 放在 enum 前,enum 是公共的,里面枚举变体也都是公用的,这个比较特殊,要注意。

super 关键字

  • super 用来访问父级模块路径中的内容,类似文件系统中的..

use 关键字

  • use 是作用域引入关键字。
  • use 同样需要遵循私有性原则,实例代码如下:
fn main(){
    // 通过引用可以让代码更精炼。
    use hello::front_of_house::hosting;
    let num = hosting::add_to_waitlist();
    println!("AAA{}", num);
}
image.png

as 关键字

  • 别名关键字,举例
use hello::front_of_house::hosting as newhost;
fn main(){
    // 通过引用可以让代码更精炼。
    let num = newhost::add_to_waitlist();
    println!("AAA{}", num);
}

打包引用多个模块

  • 如果模块重复可以通过 { } 括号区块进行打包
use std::io;
use std::io::Write;
// 可以改成
use std::io:: { self, Write} ;

pub use 重新导出名称

  • 使用 use 将路径导入到作用域内后,该名称在此作用域内是私有的。
  • pub use 重导入可以将条目引入作用域,该条目就可以被外部代码引入到他们的作用域。

通配符 * 引入

  • 通配符 * 可以把路径中所有公共条目都引入到作用域中,但是要谨慎使用,一般在测试的时候才需要,或者被用于预导入时。

使用外部包

  • 在Cargo.toml 中添加依赖的包,之后运行 cargo build 时候程序会 crates.io 寻找依赖库。
  • 举例,修改 Cargo.toml
[package]
name = "hello"
version = "0.1.0"
authors = ["Kami1983 <meetcancanyou@yahoo.com>"]
edition = "2018"

# 添加依赖 
[dependencies]
rand = "0.8.3"
  • 外部包的使用同样需要use 关键字,例如:
use rand::Rng;

fn main() {
    // 生成一个0~9的的随机数,gen_range 根据Rust 版本不同参数写法上也是有区别的需要注意
    // 较新版本的是 gen_range(0,10)
    let randnum = rand::thread_rng().gen_range(0..10);
    println!("Rand num is :  {}", randnum);
}

如何将模块拆分到不同的文件

  • 拆分是降解负责度最好的办法没有之一,所以Rust 也可以将模块内容拆分到不同的文件中的,而且分厂简单。
  • Rust 会从与模块同名的文件中加载内容,但却可以让模块树的结构不发生变化。
  • 随着模块逐渐变大,该技术可以让你把模块的内容移动到其他文件中。
  • 举例,之前有一段代码如下:
mod testmod {
    pub fn say_words() {
        println!("Hello world!");
    }
}

fn main() { 
    testmod::say_words();
}
  • 突然间觉得代码过于臃肿,要将 testmod 单独放到其他的文件中就可以简单的改进一下:
# 原来的 main.rs
// 直接 mod 名字; 就可以将该模块分离,成 testmod.rs 文件
mod testmod ;
fn main() { 
    testmod::say_words();
}
------------------ 注意这里面的内容放到  testmod.rs 单独文件中
# 分离出来的 testmod.rs
pub fn say_words() {
    println!("Hello world!");
}
image.png
  • 运行之后效果相同

结束

  • 感谢阅读,这章节还是很有意思的,因为一个好的结构化代码,离不开项目工程结构的优化和解耦。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容

  • 通用编程概念 变量与可变性 变量默认不可变,如需要改变,可在变量名前加 mut 使其可变。例如:let mut a...
    soojade阅读 12,563评论 2 30
  • 随着我们的坑越来越多,越来越大,我们必须要对各种坑进行管理了。Rust为我们提供了一套坑务管理系统,方便大家有条不...
    Jackeyzhe阅读 650评论 0 1
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young阅读 3,802评论 1 10
  • OC的理解与特性 OC作为一门面向对象的语言,自然具有面向对象的语言特性:封装、继承、多态。它既具有静态语言的特性...
    蜗牛上上升阅读 855评论 0 0
  • 1、注释的作用 单行注释: # 多行注释:三对单引号(’’’注释内容’’’) 增加程序的可读性 提高团队开发效率 ...
    繁花似锦之流年似水阅读 535评论 0 1