在第一章的代码示例 helllo world中我们用 cargo 创建一个 Rust 新项目,里面就引入了 Crate 来生成随机数,我们来深入理解 Rust 项目的一些基本概念。

  • 项目(Package):Cargo 的一个功能单元,它包含一个Cargo.toml文件,这个文件用于描述如何构建这些包,包括包的名称、版本、作者等信息,同时也定义了包的依赖项,方便构建、测试和分享。
  • 工作空间(Workspace):在大型项目里,工作空间用于管理多个相关的包。这些包可能会相互协作,工作空间可以让它们更好地协同工作,共享某些依赖等。
  • 包(Crate):它是 Rust 编译的基本单元,有两种类型:库(Library)和二进制(Binary)。库类型的包可以被其他项目作为依赖使用,二进制类型的包可以生成可执行文件运行,并且包内部是由模块组成的树形结构来组织代码。
  • 模块(Module):模块主要用于组织代码,控制代码的可见性。可以一个文件有多个模块,也可以一个文件一个模块,它是项目里代码组织的单元,让代码结构更清晰。

Rust 中的 Crate 和 package 是两个相关但不同的概念,比较容易混淆,我们来看看有什么区别。

Crate

Crate 是 Rust 的编译单元,也是你定义模块树的根。每一个 Rust 程序至少包含一个 Crate,即二进制(binary)Crate,产生可执行文件;或者库(library)Crate,可以被其他包依赖使用。

Crate 指的是最终会被编译成一个单独的目标文件(如共享库或可执行文件)的代码集合。

Crate 可以分为两种类型:

  • Binary Crates:用来生成可执行文件。每个 Crate 只能有一个 main 函数,它是程序的入口点。
  • Library Crates:可以被其他 Crate 使用。它们暴露 API 给其他 Crate,并不生成直接运行的程序。

Package

Package 是一个更高级别的概念,它是指一组源文件和相关的元数据,用来构建一个或多个 Crates。

一个 package 包含:

  • 一个 Cargo.toml 文件,这个文件定义了包的元数据,如名称、版本、作者等,并可以指定依赖的其他包。
  • 一个或多个 Crates。一个 package 默认情况下只有一个 library Crate(在 src/lib.rs 文件中定义)和任意数量的 binary Crates(在 src/bin 目录下的文件中定义)。

*简单来说,package 是一种分发和版本控制的方式,而 Crate 是其中实际编译的东西。*你可以把 package 想象成一个容器,它可以包含一个或多个 Crate,同时还包括了所有必要的配置来构建和管理这些 Crate。

当你使用 Cargo(Rust 的构建系统和包管理器)创建一个新的项目时,Cargo 会为你设置好一个 package 结构,里面通常会有一个默认的 Crate。

通过 Cargo,你可以很容易地添加、移除和更新你的项目的依赖关系,以及构建、测试和发布你的 Crate。

Cargo.toml

Cargo.toml 是 package 的元数据文件,它描述了 package 的配置信息,如名称、版本、作者、依赖等。类似于 JavaScript 的 package.json 文件。

一个简单的 Cargo.toml 文件结构看起来像这样:

[package]
name = "your_package_name"
version = "0.1.0"
authors = ["Your Name <your.email@example.com>"]
edition = "2021"
[dependencies]
# 依赖项列表
rand = "0.8.4"
[dev-dependencies]
# 测试依赖项列表
criterion = "0.3"
[build-dependencies]
# 构建依赖项列表(仅在构建脚本时使用)
cc = "1.0"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["full"] }
[features]
# 特性(features)可以用于条件编译和启用可选功能。
[profile.release]
# 发布构建配置

Package 目录

一个常见的 Package 的目录通常包含以下文件夹或者文件:

your_package_name/
├── Cargo.toml
├── Cargo.lock
├── src/
│ ├── main.rs
│ └── lib.rs
├── src/bin/
│ └── binary.rs
├── tests/
│ └── test.rs
├── examples/
│ └── example.rs
└── benches/
└── bench.rs
  • Cargo.toml:元数据文件,描述了 package 的配置信息。
  • Cargo.lock:Cargo 生成的锁定文件,用于记录当前依赖项的确切版本。
  • src:源代码目录,包含所有的 Rust 源文件。
  • src/bin:二进制 Crate 目录,包含所有的二进制 Crate 源文件。
  • tests:测试目录,包含所有的测试代码。
  • examples:示例目录,包含所有的示例代码。
  • benches:基准测试目录,包含所有的基准测试代码。

总结

在 Rust 中,Package 和 Crate 是构建和组织代码的核心概念。Package 提供了一种方式来分发和版本控制一组源文件及它们的元数据,而 Crate 则是 Rust 的编译单元,定义了模块树的根,并可以是库或二进制类型。每个 Package 至少包含一个 Crate,但也可以包含多个 Binary Crates 以及一个 Library Crate。Cargo.toml 文件是 Package 的核心,它包含了构建、测试和发布所需的所有信息。理解这些概念对于有效地管理和扩展 Rust 项目至关重要。