开发辅助工具
本章节将介绍 Rust 生态中一些有用的工具,这些工具可以帮助你在开发过程中提高代码质量、效率和可维护性。
常见工具¶
Rust 提供了一系列内置工具,帮助开发者在提高开发效率的同时,也能编写高质量、规范的代码。正确使用这些工具,可以让你更加专注于代码的逻辑,而不会被琐碎的细节所困扰。
rustc¶
Rust 编译器(rustc
)不仅能够完成编译功能。相比于 gcc 等编译器来说,它的一个重要优势即是友好的错误提示。对于 Rust 新手来说,编译器的错误提示可以帮助你快速定位问题,从而方便你更快写出正确的代码。
如果代码存在错误或者需要警告的内容,rustc
会输出详细的信息。示例代码如下:
// main.rs
fn main() {
let x = 42;
x = x + 1;
println!("{}", x);
}
我们使用 rustc 编译上述代码:
rustc main.rs
终端会输出如下结果(当前 rustc 版本为 1.85.0-stable):
error[E0384]: cannot assign twice to immutable variable `x`
--> main.rs:3:5
|
2 | let x = 42;
| - first assignment to `x`
3 | x = x + 1;
| ^^^^^^^^^ cannot assign twice to immutable variable
|
help: consider making this binding mutable
|
2 | let mut x = 42;
| +++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0384`.
上述输出结果可以分为三部分:
-
异常原因说明:
error[E0384]: cannot assign twice to immutable variable `x`
这里
E0384
是错误码,表示cannot assign twice to immutable variable
,即不能对不可变变量进行二次赋值。--> main.rs:3:5 | 2 | let x = 42; | - first assignment to `x` 3 | x = x + 1; | ^^^^^^^^^ cannot assign twice to immutable variable |
这里描述了错误发生的位置和具体的原因: -
main.rs:3:5
表示错误发生在main.rs
文件的第 3 行第 5 列。 -first assignment to x
表示x
的第一次赋值发生在第 2 行。 -x = x + 1
下的波浪线(若你的终端支持颜色输出,可以看到这是一条红色波浪线)表示错误发生的位置,这里x
被重复赋值,从而违背了 Rust 的不可变性原则。 -
改进建议:
help: consider making this binding mutable | 2 | let mut x = 42; | +++
这里给出了一个改进建议,即在
let
关键字后面添加mut
关键字,从而将x
声明为可变变量。 -
深入信息:
对于 Rust 编译器发出的错误,编译器会提供一个错误码,并给出一些可能的解释。对上述的错误,编译器给出的错误码是
E0384
。For more information about this error, try `rustc --explain E0384`.
我们可以在终端执行它给出的指令
rustc --explain E0384
,从而获取更多关于该错误的信息。更多 rustc 可能给出的错误码详见 Error Code Index。
基于 rustc 的建议,我们修改代码之后重新编译,即可得到正确的结果。
自动修复功能¶
VSCode 等现代 IDE 提供了智能修复功能,可以在编译器报错时根据其给出的建议自动修复代码。我们以上述代码为例,在 VSCode 中写入该段代码,会出现红色波浪线报错。将光标移动到红色波浪线上,会显示出具体的报错内容,如下图:
我们点击 快速修复
按钮,VSCode 会按照编译期的报错,显示如下的修复建议选项。
其中的 Copilot 选项来自于 VSCode 的 Copilot 插件,详见将 AI 集成到 IDE。我们选择第一项:Change it to be mutable(将其声明为可变变量)
选项,IDE 会自动修正代码的 bug,使其通过编译。
需要注意的是,IDE 的自动修复功能仅是辅助功能,其给出的修复建议可能并不一定正确。因此,当 IDE 无法解决问题时,我们仍然需要仔细阅读编译器的报错信息,并思考解决的方法。
clippy¶
clippy
是 Rust 官方提供的静态代码分析工具,可以帮助你发现代码中的潜在问题和改进建议,从而让你的代码更加规范、健壮。
为了使用 clippy,你需要先安装 clippy 组件:
rustup component add clippy
示例代码如下:
// src/main.rs
fn main() {
let x = true;
if x == true {
println!("x is true");
}
}
在项目根目录下运行 cargo clippy
后输出:
warning: equality checks against true are unnecessary
--> src/main.rs:3:8
|
3 | if x == true {
| ^^^^^^^^^ help: try simplifying it as shown: `x`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#bool_comparison
= note: `#[warn(clippy::bool_comparison)]` on by default
同样的,我们拆分一下 clippy 的输出结果:
-
警告信息与改进建议:
warning: equality checks against true are unnecessary --> src/main.rs:3:8 | 3 | if x == true { | ^^^^^^^^^ help: try simplifying it as shown: `x` |
这里
warning: equality checks against true are unnecessary
代表某个判断相等语句是冗余的。在我们的程序中,clippy 认为
if x == true
是冗余的,可以简化为if x
。而help: try simplifying it as shown: x
给出了改进建议,即简化为if x
。 -
深入信息:
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#bool_comparison = note: `#[warn(clippy::bool_comparison)]` on by default
这里给出了进一步的信息,说明当前的检查属于
clippy::bool_comparison
,可以访问 clippy-docs 获取更多信息。
可以使用 #[allow(...)]
属性来禁用特定的检查,屏蔽警告。但是,除非额外启用了一些非常严格的检查规则,默认的规则基本上总是应当遵守的,如果没有非常充分的理由,不应该随意禁用检查。如果你不理解 clippy 提示警告的原因,不知道应该如何修复,可以阅读 help:
中链接的文档,也可以向 AI 和助教求助。
集成 clippy 到 IDE
如果你使用 VSCode 及其衍生的编辑器进行开发,还可以将 clippy 集成到 IDE 的自动检查中和修复中,从而避免了手动调用的麻烦。我们以 VSCode 的 rust-analyzer 插件为例:
-
打开命令面板 (快捷键为
Ctrl+Shift+P
/Cmd+Shift+P
) -
键入
Preferences: Open Settings (JSON)
,从而打开 settings.json 文件。 -
在 settings.json 中加入:
{ // Default command is `cargo check` "rust-analyzer.check.command": "clippy", }
上文中,我们设置 rust-analyzer 的检查命令为 clippy
。当我们启用了 rust-analyzer 的 checkOnSave
功能(默认是启用的,可以在设置中查找)之后,每次保存文件时,都会自动调用 rust-analyzer.check
命令,从而调用 clippy 实现自动检查。
rustfmt¶
rustfmt
也是 Rust 官方提供的代码格式化工具,可以帮助你保持代码风格一致。
为了使用 rustfmt,你需要先安装 rustfmt 组件:
rustup component add rustfmt
我们提供一个未格式化的示例代码:
// src/main.rs
fn main(){println!("hello");}
可以看到,代码的格式并不美观。当我们执行如下指令:
rustfmt src/main.rs
可以看到,源文件的代码格式得到了改善。
// src/main.rs
fn main() {
println!("hello");
}
当我们使用 cargo 管理项目时,也可以通过 cargo fmt
来执行代码格式化,此时本质上仍然是调用了 rustfmt。
rustfmt 的格式化规范是可配置的,默认格式详见 The Default Rust Style。自定义配置的方法和更多选项详见 rustfmt docs。
自动格式化¶
当我们使用 VSCode 等现代 IDE 开发时,可以借助 IDE 的自动格式化功能,在保存代码时自动调用 rustfmt 进行格式化,从而避免了手动调用指令的麻烦。
以 VSCode 为例,配置自动格式化的步骤如下:
此时在编辑完 Rust 代码之后保存(快捷键一般为 Ctrl+S
/ Cmd+S
),即可自动调用对应的格式化工具。对于 rust-analyzer 来说,默认调用 rustfmt 进行格式化。
这些工具可以帮助你在开发过程中及时发现问题、保持代码整洁,提高开发效率。
扩展工具¶
除去上述提到的常见工具,Rust 生态中来自官方或者第三方维护者的更多工具。这些工具可以帮助你发现代码中的潜在问题和改进建议,从而让你的代码更加规范、健壮。但它们的安装和使用相对复杂,且需要一定的学习成本,因此本章节仅介绍其基本信息。感兴趣的同学可以进一步了解。
工具类别 | 子类别 | 工具 | 重要程度 | 来源 | 说明 |
---|---|---|---|---|---|
程序分析工具 | |||||
👉 | 静态检查工具 | ||||
clippy | ⭐⭐⭐ | clippy | 捕获常见的编码错误,并使代码更加地道 | ||
mirai | ⭐⭐ | 论文 | 检查 panic;支持属性标注 | ||
rapx | ⭐⭐ | RAPx book | 检查 UAF 和内存泄露 | ||
lockbud | ⭐⭐ | 论文 | 检查 deadlock 等并发问题 | ||
atomvchecker | ⭐⭐ | 论文 | 检查 memory ordering misuse | ||
rudra | ⭐⭐ | 论文 | 检查 panic safety 和 Send/Sync Variance | ||
👉 | 动态检查工具 | ||||
测试 | ⭐⭐⭐ | cargo-test | 单元测试或集成测试等 | ||
miri | ⭐⭐⭐ | cargo-miri | 最高质量的 UB 检查结果 | ||
辅助检查工具 | |||||
👉 | 格式化检查 | fmt | ⭐⭐⭐ | [rustfmt] | 检查未格式化的代码 |
👉 | 供应链审查 | ||||
audit | ⭐⭐⭐ | cargo-audit | 检查是否存在已报告安全漏洞的依赖版本 | ||
udeps | ⭐⭐ | 尽可能消除无用的依赖 | |||
outdated | ⭐ | 尽可能使用最新的依赖 | |||
👉 | 代码统计 | geiger | ⭐ | 尽可能警惕不安全代码 | |
👉 | 版本语义检查 | semver | ⭐⭐ | semver crate | 一个严肃的发版应该遵循语义化版本控制 |
AI 辅助开发¶
近些年来 AI 辅助开发工具已经逐渐成熟,并开始在开发过程中发挥重要作用。我们将介绍一些可用的 AI 工具,并介绍如何使用它们来辅助开发。
与 Chatbot 交互¶
近年来,Chatbot 已经逐渐成为开发者的得力助手。通过与 Chatbot 交互,开发者可以快速获取信息、解决问题,从而提高开发效率。
国内 Chatbot 的使用门槛较低,方便同学们快速上手使用,其包括:
对于有兴趣的同学,还可以尝试使用国外一些较为知名的 Chatbot,包括:
国外的 Chatbot 常需要使用特殊手段进行访问、注册,同学们可以自行搜索相关方法。
你可以通过和 Chatbot 交互来解决自己的知识困惑,或协助完成一些调试任务。在本课程中,可被允许使用 Chatbot 的场景详见使用原则。
将 AI 集成到 IDE¶
IDE 全称为 Integrated development environment(集成开发环境),是一种辅助程序开发人员开发软件的应用软件。它通常集成了多个功能组件,比如:
-
代码编辑器(Code Editor)
-
调试器(Debugger)
-
自动补全 / 语法高亮 / 重构工具
-
项目资源管理器(Project Explorer)
你可以把 IDE 理解为开发者的工具台:所有工具都在一个地方,可以直接编译运行、排查 bug、搜索符号、自动补全等。值得强调的是,对于不同的开发需求(如不同编程语言、图形化等),可能会有不同的适配 IDE。本课程建议大家使用 VSCode 进行开发,在大家熟悉 VSCode 后,可以尝试使用其他 IDE,如 XCode、JetBrains 系列等。
将 AI 集成到 IDE 中,可以显著提高开发效率。例如,在 VSCode 中可以安装 Github Copilot 等插件,从而达到生成注释、补全代码等目的。你可以在 VSCode 的扩展商店中输入 Copilot
进行搜索,并安装对应的扩展。安装完成之后,你可以尝试使用 Copilot 的代码补全功能。下图是一个示例。
在上图示例中,我们在第 4 行给出了对 a 和 b 运算的目标(即计算 a 和 b 的和),此时 Copilot 会以灰体的形式给出一个代码补全的建议,我们可以按下 Tab
按键以接受这个建议,此时代码会自动补全为:
fn main() {
let a = 1;
let b = 2;
// 计算 a 和 b 的和
let sum = a + b;
}
Github Copilot 学生身份激活
Github Copilot 需要付费使用,但我们可以申请以学生身份免费访问 Copilot Pro,详见以学生、教师或维护者身份免费访问 Copilot Pro。
使用原则¶
AI 的功能很强大,但是我们不能完全依赖 AI 来完成开发。我们使用 AI 工具的原则是:课程作业的主体必须由学生本人独立完成,AI 仅可用于辅助开发,不可直接生成或抄袭作业的核心内容。人性是经不住考验的,所以不要考验自己。如果你觉得自己不能拒绝诱惑,那就不要用 AI。
在本课程中,我们允许使用 AI 的场景包括:
-
代码片段补全:在编写代码时,可以用 AI 辅助完成简单的代码补全,如意义相近的分支判断、循环结构等。如下列分支代码可以通过 AI 辅助完成补全:
AI 可以快速补全从 4 到 10 的剩余分支内容,从而提高开发效率。fn to_english(n: &str) -> &str { // 将 1 到 10 的数字转化为英文 match n { "1" => "one", "2" => "two", "3" => "three", // ... _ => "unknown", } }
-
格式化文档:可被 AI 规范化的文档包括代码注释、项目报告等,AI 可以帮助格式化文档,从而使其更加规范、易读。
-
辅助调试:如将报错信息和对应源码发送给 AI,让 AI 帮助你分析问题所在,从而协助找出问题。
-
询问思路:对于某个具体实现问题,可以询问 AI 一些关于实现思路的问题,但是不要让 AI 直接生成代码。
需要注意的是,AI 提供的答案不一定是正确的。如果 AI 的回答有所帮助,需要在代码或 HONOR CODE 中明确注明,从而让课程组了解实际情况。
如何注明对 AI 的使用情况
在代码中:
// Inspired from ChatGPT:
// <answer from ChatGPT>
在 HONOR CODE 中:
关于 <problem>,我向 ChatGPT 提问了 <question>,ChatGPT 回答了 <answer>,启发了我在 <code> 中的实现。
样例:
关于如何重构 Rust 项目的问题,我向 ChatGPT 提问了:在 Rust 里面,如果我想让多个二进制程序共用一部分代码,我该怎么做?
ChatGPT 回答了:
在 Rust 中,如果你想让多个二进制程序共用一部分代码,可以使用 Rust 的模块系统。
首先,将你希望共用的代码放到单独的 Rust 模块中,可以是一个单独的源文件或一个子目录。创建一个名为 `lib.rs` 的文件,这个文件必须包含一个名为 `mod` 的声明,指向你的模块代码的文件或目录:
```
// src/my_shared_code/lib.rs
mod my_module {
// 公共代码
}
```
然后,在你的二进制程序的 `Cargo.toml` 文件中,添加一个依赖项,指向你的共享代码模块:
```
[dependencies]
my_shared_code = { path = "./path/to/my_shared_code" }
```
最后,在你的二进制程序的代码中,使用 `use` 语句导入你的共享代码:
```
// src/my_binary.rs
use my_shared_code::my_module;
fn main() {
// 使用共享代码
}
```
这样你的二进制程序就可以使用共享代码模块中的代码了。你还可以在其他二进制程序中重复使用同一共享代码模块。
这启发了我的作业的代码组织方式。
以下内容是不被允许的:
-
直接使用 AI 生成作业主体代码:如将作业要求直接输入给 AI,让 AI 给出对应代码。
-
使用 AI 翻译、伪原创已有内容,使其看似原创,从而逃避抄袭检测。
-
使用 AI 生成整篇实验报告,并未经过学生充分理解和改写。
若在核查过程中发现了课程组不允许的行为,将可能以抄袭行为处理,详见抄袭与查重。