Rust通过包和模块来组织所有的代码,其中每一个Rust项目都是一个包。平时所说的实现给中功能的第三方库每一个都是一个包,这些库都是以一个包的形式发布。
包
一个Rust项目可以依赖其他的包,这只需要在 Cargo.toml 的 [dependencies] 中列出即可。所有在 Cargo.toml 中列出的被依赖包,都可以需要使用它们的代码文件中使用 extern crate 声明使用。
例如有以下依赖:
[dependencies]# 这里没有书写任何被依赖库的版本,*代表使用最新版本image = "*"
那么在 main.rs 文件的开头就需要这样来引用。
extern crate image;
模块
模块是Rust中代码的命名空间,是函数、类型、结构体等代码的容器。包解决的是Rust项目间代码共享的问题,而模块解决的是项目内部代码组织的问题。模块可以嵌套,一个模块拥有一系列的子模块是非常常见的。
如果把所有的模块都书写在一个文件中,那么可以采用以下形式。
mod master_module {pub mod sub_module_1 {// 这个子模块是公共的,可以被其他的模块访问到...}mod sub_module_2 {// 这个子模块是私有的,从其他的模块是无法访问到的...}}
模块中的内容默认都是私有的,只有添加了
pub关键字以后,才会变为公共的,可以被外部访问到。
如果需要把模块定义在独立的文件或者文件夹中,那么就需要使用模块的声明语法了。假设有以下项目结构。
在这个项目中, direct.rs 是一个存在于独立文件的模块,目录 composite 是一个存在与独立文件夹的模块,所以这两个模块都需要在 main.rs 中声明。在 main.rs 文件的开头就可以如下一样声明。
pub mod direct;pub mod composite;
这样一来,如果在 main.rs 同目录下,如果存在 direct.rs ,Rust就会把 direct.rs 作为一个模块来对待,并且在 direct.rs 文件中不必再使用 mod 关键字声明模块了。对于目录 composite ,Rust会首先去寻找其中的 mod.rs 文件,这个文件是使用目录作为模块的统领文件,其下的所有子模块也都是在这个 mod.rs 文件中定义。
模块 composite 下的子模块需要在 mod.rs 文件中定义,其中内容如以下示例所示。
pub mod analysis;pub mod statistics;
mod.rs 文件中除了可以包含子模块的定义以外,要包含的还有当前模块中需要定义的功能内容。
内容导入
在任何时候,都可以使用操作符 :: 采用绝对路径的方式访问模块中的内容,例如从 main.rs 访问 analysis.rs 中定义的内容就如同下面这样。
::composite::analysis::AnalysisDefinedContent
这些书写较为繁琐,所以可以提前使用 use 关键字将要使用的内容导入。导入会让被导入的内容成为当前模块中的一个局部别名。 use 关键字会自动转换根路径,所以不需要使用最前导的 :: 操作符。例如导入上例的内容,格式就如下所示。
use composite::analysis::AnalysisDefinedContent;// 还可以一次性导入多个内容use composite::analysis::{AnalysisDefinedContent, AnotherUseableContent};// 或者直接导入全部内容use composite::analysis::*;// 导入一个模块use composite::analysis;
使用 use 导入模块中的内容不仅可以导入具体内容,还可以导入一个模块,这样模块中可访问的内容就可以使用 module::content 的格式来访问了。
模块不会从其父模块继承名字,子模块也看不到父模块中定义的内容,即便这些内容都是公共的。如果要在子模块中使用父模块中定义的内容,需要使用以下声明明确导入父模块声明的内容。
use super::ParentDefinedContent;
然而父模块要访问子模块中定义的内容,也同样需要明确导入。
use self::ChildModule::ChildDefinedContent;
