头图

一、简介

 ___________________________________________________________
/ 了解了 Rust 的基本语法,紧接着就需要了解 Rust             \
| 应该如何良好的代码结构, 当然此处不需要对 Cargo           |
\ 的所有功能都了解,但是需要 cargo 的基本创建、构建等命令。 /
 -----------------------------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

二、Cargo 基础命令

回顾 Cargo 基本命令

命令描述
cargo new app创建一个可运行的程序。
cargo new crate1 --lib创建一个库。
cargo build构建项目。
cargo watch监听文件更改并自动重新构建项目。
cargo test运行测试。
cargo fmt代码格式化。

2.1) cargo run

run 的命令相对实用命令,复杂的可以实用 cargo run --help 获取:

命令描述
cargo run在当前项目中编译并运行代码。
cargo run -p <pkg>在具有多个包的项目中,指定要运行的特定包。
cargo run --release以 release 模式编译并运行代码,进行优化以提高性能。
cargo run --example <example_name>运行项目中的示例代码。要指定要运行的示例名称,请用 <example_name> 替换示例的名称。

2.2) Cargo 配置文件 Cargo.toml

以下是一个: Cargo.toml 的使用示例

# 项目元信息
[package]
name = "demo5" # name 名字
version = "0.1.0" # 版本
edition = "2021" # Rust 八本
authors = ["Your Name <you@example.com>"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde = "1.0"
rand = { version = "0.8", features = ["std"] }

# 其他的写法
crate_name = "0.0.1" # 基础些法
crate_name1 = { version = "0.1.2", features = ["feature1", "feature2"] } # 详细写法
crate_name2 = { git = "https://github.com/user/crate_name.git", branch = "main" } # git 写法
web = { path = "./src/web"} # 本地路径
my_alias = { package = "crate_name", version = "0.1.2" } # 别名
crate_name3 = { version = "0.1.2", optional = true } # 添加特性
# 允许多个版本
crate_name4 = "1.2.3"
crate_name5 = { version = "2.0.0", package = "different_crate_name" }

[dev-dependencies]
tokio = { version = "1", features = ["full"] }

[build-dependencies] # 针对构建时依赖项的配置部分。
bindgen = "0.60" # 构建时依赖的 bindgen crate 的版本

[workspace] # Workspace 中的成员 crates 的路径列表。
members = ["crates/lib/core", "crates/lib/auth"] # 设置允许你指定一个包含多个 crates 的 Workspace,每个成员 crate 可能位于不同的目录下。

[lib] # 针对库文件的配置部分。
path = "src/lib.rs" # 库文件的路径。

[[bin]] # 定义多个可执行文件。
name = "my_binary" # 指定了可执行文件的名称,要生成的二进制文件的名称。
path = "src/main.rs" # 指定了这个可执行文件的入口点,也就是 Rust 源代码文件的路径。

[profile.dev] # 针对开发(debug)构建配置的部分。
opt-level = 0 # opt-level = 0 表示不开启优化,编译速度较快,但生成的代码可能不够高效。

[profile.release] # 针对发布(release)构建配置的部分。
opt-level = 3 # opt-level = 3 表示启用最高级别的优化,会生成最优化的代码,以提高执行效率。

三、Crates

crate 翻译是箱子,在其他的软件领域一般叫包,箱子可以分为三类,crate分类可以分为三类:

类型描述
根 crates包含多种类型的 Rust crates 的目录。
可执行二进制 crates包含可直接执行的 Rust 二进制文件的 crates。
lib crates包含库(Library)的 Rust crates。

四、Project 项目

一个项目通常包含一个 Cargo.toml 文件。

✅这个文件描述了项目的元信息,比如名称、版本、作者、依赖等。在一个项目中可以包含一个或多个 crates。

五、Crates

每一个 Crates 都有一个 Cargo.toml 文件。描述其自身的元信息和依赖关系。值得注意的是:

✅一个项目可以由一个或多个 crates 组成,这些 crates 可以互相依赖。Crates 配合 Cargo 一起管理 Rust 代码。

六、Mod 模块

mod 是 Rust 中的关键字,在 Rust 内部模块中包含两种模块方式:

  • 二进制(用于直接运行配合 cargo run)
  • 库类(一般提供给程序的依赖)

此处关注的,Rust 编程时内部模块,mod 关键字一般与 use 关键字一起使用。当然模块中的内容访问方式使用 :: 进行访问。

6.1) 模块涉及的关键字

  • mod 定义一个模块
  • use 文件模块
  • pub 公开性
  • crate 根模块

6.2) 创建一个项目(二进制可执行)

cargo new app-demo

6.3) 模块的基本内容

  • 函数/方法
  • 结构体/枚举
  • 常量和变量
  • 内部模块
  • 外部 crate 和依赖
  • 文档和注释
  • 模块

6.4) Rust 根模块

整个 Rust 项目的起点:

  • 可执行文件,例如 main.rs 就是根模块
  • 库,例如 lib.rs 就是根模块

6.5) 定义 Rust 内部文件模块

在 src 目录下创建模块

cd src
touch about.rs
  • 定义 about.ts 模块内容:
pub mod abc {
    pub fn ab() {
        println!("this is ab");
    }
}

fn abc() {
  println!("{}", "this is abc");
}
  • 用 use 使用 about 模块
use about;

fn main() {
    about::abc();
}

6.6) 定义内部文件夹模块

定义文件模块的特点是:需要一个 mod.rs 文件夹。在 mod 中暴露内容

  • 创建 news 模块文件
mkdir news/
touch mod.rs
  • 在 mod.rs 中定义模块内容:
pub fn create_out_news() {}
pub mod news {
    // your mode
    pub fn create_news(){}
}

使用方式与单文件模块一致。

6.7) 创建一个应用程序

cargo new app

6.8) 创建一个二进制库

cargo new my_library --lib

6.9) 在 Toml dependencies 中引入库

[dependencies]
my_library = { path = "/path/to/your/my_library" }

6.10) 使用二进制库

使用 use 关键字使用库:

// 在 my_app 中使用 my_library 中的函数
use my_library;

fn main() {
    my_library::greet("World");
}

七、workspace 多可运行二进制

  • 需要 members 注册
  • 需要 cargo run -p <pkg>
  • 创建项目
cd your_dir
cargo new app
cd app 
cargo new sub-app1

如果我们需要在根目录下运行 sub-app1 我们需要注册 sub-app1 到主项目,

[workspace]
members = ["sub-app1"]

运行:

cargo run -p sub-app1

如果我们有多个项目需要运行,此时具有较大的作用。

八、代码格式化以及配置

cargo 提供了 cargo format 进行格式化,当然它也是可以配置的, 以下一个简单的配置:

edition = "2021"  # 指定了 Rust 代码的版本为 2021 Edition
newline_style = "unix"  # 指定了换行符的风格为 Unix 风格的换行符(\n)
unstable_features = true  # 允许使用不稳定的 Rust 特性
format_code_in_doc_comments = true  # 允许在文档注释中对代码进行格式化,以增强代码在生成文档时的可读性
max_width = 180  # 指定代码行的最大宽度为 180 个字符
normalize_comments = true  # 规范化注释,可能会将注释调整为统一的格式
wrap_comments = true  # 允许对长注释进行换行,以保持注释的可读性

[group_imports]
style = "std_external_crate"  # 控制导入的分组方式,设置为按标准库和外部 crate 分组
[imports_granularity]
style = "crate"  # 控制导入的粒度,设置为按 crate 进行导入

九、企业级的 web 项目目录结构推荐

rust-web-app

├── Cargo.lock
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── crates
│   ├── libs
│   │   ├── lib-auth
│   │   ├── lib-core
│   │   ├── lib-rpc
│   │   └── lib-utils
│   ├── services
│   │   └── web-server
│   └── tools
│       └── gen-key
├── rustfmt.toml
├── sql
│   └── dev_initial
│       ├── 00-recreate-db.sql
│       ├── 01-create-schema.sql
│       └── 02-dev-seed.sql
└── web-folder
    └── index.html

所有的库代码都在 crates/ 中,启动 Rust web 服务,libs 存放了所有的库。web-folder 存放了 html 相关的内容。当然一个企业级的项目可能会用大 docker 这种方方便运维的工具,这里不是重点这里就不说明了。

十、小结

本文主要目的对 Rust Cargo 组合代码还有问题的,存在疑问的总结与探索和实践。当基本上熟悉了 Rust 的语言的语法,接下一定熟悉 Rust 如何管理自己的代码结构,能够开始做一些复杂的项目。本文主要讲解 Cargo 的基本用法,希望对读者有帮助。


进二开物
44 声望1 粉丝

兴趣使然 [👀欢迎关注公棕号:进二开物, 更多文章包含 JavaScript/TypeScript/Rust 等编程语言,以及科技信息分享。]