前言

目前为止,我们所有的代码示例都是单文件。现在让我们看怎么组建一个项目。

模块

每个Rust程序或者库都叫做 crate

每个 crate都由模块的层次结构组成

每个 crate都有一个跟模块

模块里面可以有全局变量、全局函数、全局结构体、全局 Trait甚至是全局模块!

在Rust中,文件与模块树的层次结构并不是一对一的映射关系。我们必须在我们的代码中手动构建模块树。

编写程序

应用程序的根模块需要在一个叫 main.rs 的文件里面。

编写库

库的根模块需要在一个叫 lib.rs 的文件里面。

引用其他模块和 crate

我们可以使用完整的模块路径引用模块中的项目: std::f64::consts::PI 更简单的方法是使用 use 关键字。此关键字可以让我们在代码中使用模块中的项目而无需指定完整路径。例如 use::std::f64::consts::PI 这样我们在main函数中就只需写 PI 就可以了。

std 是Rust的标准库。这个库中包含了大量有用的数据结构和与操作系统交互的函数。

use std::f64::consts::PI;

fn main() {

println!("欢迎来到练习场!");

println!("我想要一块 {}!", PI);

}

引用多个项目

在同一模块路径中可以用多个项目,例如: use std::f64::consts::{PI, TAU}

创建模块

当我们想到项目时,我们通常会想象一个以目录组织的文件层次结构。Rust允许我们创建与我们的文件结构密切相关的模块。

在Rust中,有两种方式声明一个模块。例如,模块 foo 可以表示为:

一个名为 foo.rs 的文件在名为 foo 的目录,里面有一个叫 mod.rs 文件。

模块层次结构

模块可以项目依赖。要建立一个模块和其子模块之间的关系,你需要在父模块中这样写: mod foo; 上面的声明将编译器寻找一个名为 foo.rs 或 foo/mod.rs 的文件,并将其内容插入这个作用域内名为 foo 的模块中。

内联模块

一个子模块可以直接内联在一个模块的代码中。 内联模块最常见的用途时创建单元测试。下面我们创建一个只有在使用Rust进行测试时才会存在的内联模块!

// 当 Rust 不在测试模块,这个宏会删除这个内联模块

#[cfg(test)]

mod test {

// 请注意,我们并不能立即获得对父模块的访问。

use super::*;

... 测试单元写在这里 ...

}

模块内部引用

你可以在你的 use 路径中使用如下Rust关键字来获得我们想要的模块:

crate - 我们的crate的根模块super - 当前模块的父模块self - 当前模块

导出

默认情况下,模块的成员不能从模块外部访问(甚至它的子模块也不行!)。我们可以使用 pub 关键字使一个模块的成员可以从外部访问。

默认情况下,crate 中的成员无法从当前 crate 之外访问。我们可以通过根模块中(lib.rs 或 main.rs),将成员标记为 pub 使它们可以访问。

结构体可见性

就像函数一样,结构体可以使用 pub 声明他们想要在模块外暴露的东西。

// SeaCreature 结构体在我们的模块外面也能使用了

pub struct SeaCreature {

pub animal_type: String,

pub name: String,

pub arms: i32,

pub legs: i32,

// 我们把武器信息保密好了

weapon: Sting,

}

Preclude

为什么我们在没有 use 导入 Vec 或 Box 的情况下却可以到处使用。这是因为标准库中有一个叫 preclude 的模块。 以 std::preclude::*导入的任何东西都会自动提供给Rust的各个部分。Vec 和 Box 便是如此,并且其他东西(Option、Copy等)也是如此。

我们自己的Preclude

我们自己的库里面最好也有一个自己的preclude模块。这个模块可以作为其他使用我们的库的用户的起点:他们可以借此导入你库里面所有的常见的数据结构(例如 use my_library::preclude:)。当然,这个模块就不会在我们的库的程序或者别的库里面自动启用了。不过使用这个惯例的话,大家会很轻松知道从何开始的。

总结

学会这个我们就可以创建与世界分享我们的Rust应用程序和库了。

参考链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。