Rust 代码结构组织从基础到实践

一、简介

sh 复制代码
 ___________________________________________________________
/ 了解了 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 的使用示例

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) 创建一个项目(二进制可执行)

sh 复制代码
cargo new app-demo

6.3) 模块的基本内容

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

6.4) Rust 根模块

整个 Rust 项目的起点:

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

6.5) 定义 Rust 内部文件模块

在 src 目录下创建模块

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

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

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

6.6) 定义内部文件夹模块

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

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

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

6.7) 创建一个应用程序

sh 复制代码
cargo new app

6.8) 创建一个二进制库

sh 复制代码
cargo new my_library --lib

6.9) 在 Toml dependencies 中引入库

toml 复制代码
[dependencies]
my_library = { path = "/path/to/your/my_library" }

6.10) 使用二进制库

使用 use 关键字使用库:

rs 复制代码
// 在 my_app 中使用 my_library 中的函数
use my_library;

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

七、workspace 多可运行二进制

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

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

toml 复制代码
[workspace]
members = ["sub-app1"]

运行:

sh 复制代码
cargo run -p sub-app1

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

八、代码格式化以及配置

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

toml 复制代码
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

sh 复制代码
├── 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 的基本用法,希望对读者有帮助。

相关推荐
G探险者10 分钟前
如何找到那些慢 SQL?
后端·sql
雨雨雨雨雨别下啦12 分钟前
Vue3——RabbitShopping
前端·javascript·vue.js
敖正炀13 分钟前
线程池拒绝策略场景分析
后端
BumBle17 分钟前
从声明式到命令式:Vue3 弹窗组件的工厂模式重构
前端
神奇小汤圆19 分钟前
别再乱写并发了!弄懂阻塞队列,解决 90% 线程安全问题
后端
敖正炀21 分钟前
线程池决绝策略
后端
恋猫de小郭23 分钟前
你的蓝牙设备可能正在泄漏你的隐私? Bluehood 如何追踪附近设备并做隐私分析
android·前端·ios
Moe48843 分钟前
WebSocket :从浏览器 API 到 Spring 握手、Handler 与前端客户端
java·后端·架构
神奇小汤圆1 小时前
探索springboot程序打包docker的最佳方式
后端