rust模组服没了_Rust 模块和文件 - [译]

收藏数比赞数还多:)什么情况。快1万字的文章翻译不易,求个赞

不久前,我在推特上发起了 Rust 有什么让人困惑的 话题,热度最高的主题是“模块系统是怎么映射到文件的?”。

我记得刚接触 Rust 时模块让我痛苦挣扎,所以我尝试用一种我认为说得通的方式解释它。

要点

以下所述均使用 Rust 2018 版本。我没有兴趣学习(或教授)老版本的细节,特别是因为老版本让我更加困惑。

如果你有现存的项目,你可以查看 Cargo.toml 文件中的 edtion 查看项目使用的 Rust 版本。 如果没有,那现在就加上 edition = 2018。

如果使用最新的 Rust 且通过 cargo new/ cargo init 来创建新项目,新项目会自动选择 2018 版本。

什么是 crate

一个 crate 通常来说是一个项目。它有一个 Cargo.toml 文件,这个文件用于声明依赖,入口,构建选项等项目元数据。 每个 crate 可以独立地在 https://crates.io/ 上发表。

假设我们要创建一个二进制(可执行)项目:cargo new --bin(或者在已有项目上用 cargo init --bin)会为新 crate 生成一个 Cargo.toml 文件。

项目入口为 src/main.rs

对于二进制项目,src/main.rs 是项目主模块的常用路径。它不一定是精确的路径,可以在 Cargo.toml 添加相应配置 [^1],使编译器在别处查看(甚至可以有多个目标二进制文件和多个目标库)。

默认情况下,我们的可执行项目的 src/main.rs 如下:

fn main(){println!("Hello world!");}

我们可以通过 cargo run 构建和运行这个项目,若只想构建项目,则运行 cargo build

构建一个 crate 的时候,cargo 下载并编译所有所需依赖,默认情况下把临时文件和最终生成文件放入 ./target/ 目录下。 cargo 既是包管理器又是构建系统。

crate 依赖

让我们向刚才创建的 crate 添加 rand 依赖来看看命名空间是怎么工作的。我们需要修改 Cargo.toml,其内容如下:

[package]

name = "modules"

version = "0.1.0"

edition = "2018"

[dependencies]

rand = "0.7.0"

如果我们想学习如何使用 rand crate,有以下几种方式:rand 的 crates.io.page - 上面通常包含了一个类似 README 文件,包含了简要描述和一些代码示例

rand 的 文档(在 crates.io 页面标题或最新版本下有链接)。需要注意的是所有发表在 crates.io 的 crate 会在 https://docs.rs 上生成文件 - 我不确定为什么 rand 也文档部署在它自己的网页,或许它早于 docs.rs?

它的 源码页,如果其他方式(如 crates.io 的链接和自动生成的文档)失败了的化

现在让我们在 src/main.rs 里使用 rand, src/main.rs 如下:

fn main(){letrandom_boolean=rand::random();println!("You {}!",ifrandom_boolean{"win"}else{"lose"});}

请注意:我们不需要使用 use 指令来使用 rand - 它在项目下的文件全局可用,因为它在 Cargo.toml 中被声明为依赖(rust 2018之前的版本则不是这样)

我们完全没必要使用 mod (稍后讲述)

为了明白这篇博客的余下部分,你需要明白 rust 模块仅仅是命名空间 - 他们让你把相关符号组合在一起并保证可见性规则。我们的 crate 有一个主模块(我们现在所在),它的源在 src/main.rs

rand crate 也有一个入口。因为他是一个库,默认情况下其主入口为 src/lib.rs

在我们主模块范围,我们可以在主模块通过依赖名称使用依赖

总之,我们现在只处理两个模块:我们项目主入口还有 rand 的入口。

use 指令

如果我们不喜欢一直这样写 rand::random(),我们可以把 random 注入主模块范围。

userand::random;// 我们可以通过 `rand::random()` 或 `random()` 来使用它fn main(){ifrandom()&&random(){println!("You won twice in a row!");}else{println!("Try again...");}}

我们也可以使用通配符来导入 rand 主模块导出的所有符号。

// 这会导入 random,还有 thead_rng 等userand::*;fn main(){ifrandom(){panic!("Unlucky coin toss");}println!("Hello world");}

模块不需要在分开的文件里

正如刚才所见,模块是一个让你组合相关符号的语言结构。

你不需要把他们放在不同的文件下。

让我们修改下 src/main.rs 来证明这个观点ÿ

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值