工具是使编程语言实用和高效的重要组成部分。Rust 一直拥有一些出色的工具(特别是 Cargo,作为一流的包管理器和构建工具享有盛誉),而 2018 版本包含了更多工具,我们希望这些工具能进一步提升 Rust 用户的体验。
在这篇博客文章中,我将介绍 Clippy 和 Rustfmt——这两个工具已经存在了几年,现在已经稳定并可供普遍使用。我还会介绍 IDE 支持——这是许多用户的关键工作流程,现在得到了更好的支持。我将首先谈谈 Rustfix,这是一个对我们的版本迁移计划至关重要的新工具。
Rustfix
Rustfix 是一个用于自动修改 Rust 代码的工具。它是我们 2018 版本迁移故事的关键部分,使得从 2015 版本到 2018 版本的过渡变得更容易,在许多情况下甚至是完全自动的。这至关重要,因为如果没有这样的工具,我们将非常受限于用户能够接受的破坏性更改类型。
一个简单的例子
上面这段代码在 Rust 2015 中是合法的,但在 Rust 2018 中不是(方法参数必须显式指定)。Rustfix 将上面的代码更改为
有关如何使用 Rustfix 的详细信息,请参阅这些说明。要将代码从 2015 版本过渡到 2018 版本,请运行 cargo fix --edition
。
Rustfix 功能强大,但并不完美。当它无法修复您的代码时,它会发出警告,通知您需要手动修复。我们正在继续努力改进。
Rustfix 通过自动应用编译器的建议来工作。当我们添加或改进编译器修复错误或警告的建议时,Rustfix 也会得到改进。我们在 IDE 中使用相同的信息来提供快速修复(例如自动添加导入)。
感谢 Pascal Hertleif (killercup)、Oliver Scherer (oli-obk)、Alex Crichton、Zack Davis 和 Eric Huss 开发了 Rustfix 及其使用的编译器 lint。
Clippy
Clippy 是 Rust 的一个 linter。它有大量的 lint(目前有 290 个!),帮助提高程序的正确性、性能和风格。每个 lint 都可以打开或关闭(allow
),并配置为错误(deny
)或警告(warn
)。
一个例子:iter_next_loop
lint 会检查你是否因为迭代 next
的结果而不是你调用 next
的对象而犯了错误(将 while let
循环改为 for
循环时很容易犯这个错误)。
for x in y.next
将给出错误
error: you are iterating over `Iterator::next()` which is an Option; this will compile but is probably not what you want
--> src/main.rs:4:14
|
4 | for x in y.next() {
| ^^^^^^^^
|
= note: #[deny(clippy::iter_next_loop)] on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#iter_next_loop
Clippy 通过扩展 Rust 编译器来工作。编译器支持一些内置的 lint,Clippy 使用相同的机制,但提供了更多的 lint。这意味着 Clippy 的错误/警告格式应该很熟悉,您应该能够在 IDE 中(或使用 Rustfix)应用 Clippy 的建议,并且这些 lint 是可靠和准确的。
借助 Rust 1.31 和 2018 版本,Clippy 在稳定版 Rust 上可用,并具有向后兼容性保证(如果它有版本号,那将是 1.0)。Clippy 具有与 rustc 相同的稳定性保证:可以添加新的 lint,并且可以修改 lint 以增加更多功能,但是 lint 永远不会被移除(只会弃用)。这意味着使用 Clippy 编译的代码将继续使用 Clippy 编译(前提是没有通过 deny
将 lint 设置为错误),但可能会抛出新的警告。
可以使用 rustup component add clippy
安装 Clippy,然后使用 cargo clippy
运行它。有关更多信息,包括如何在 CI 中运行它,请参阅仓库 readme。
感谢 Clippy 团队 (Pascal Hertleif (killercup), Oliver Scherer (oli-obk), Manish Goregaokar (manishearth), 和 Andre Bogus (llogiq))!
Rustfmt
Rustfmt 是一个用于格式化源代码的工具。它可以将任意的、混乱的代码转化为整洁、风格优美的代码。
自动格式化可以节省您的时间和精力。您在编写代码时无需担心风格问题。如果在 CI 中使用 Rustfmt (cargo fmt --check
),则在代码审查时无需担心代码风格。通过使用标准风格,您可以让新贡献者更熟悉您的项目,并避免关于代码风格的争论。Rust 的标准代码风格是 Rustfmt 的默认风格,但如果您必须,可以对 Rustfmt 进行广泛的自定义。
Rustfmt 1.0 是 2018 版本发布的一部分。它应该适用于所有代码,并且在 2.0 版本发布之前将保持向后兼容。这里的向后兼容是指,如果您的代码已格式化(即排除阻碍格式化的 bug 或无法编译的代码),它将始终以相同的方式格式化。此保证仅在使用默认格式选项时适用。
Rustfmt 尚未完成。格式化并不完美,特别是我们不触及注释和字符串字面量,并且在宏定义和某些宏使用方面相当受限。我们很可能会在此处改进格式化,但在 2.0 版本发布之前,您需要选择启用这些更改。我们确实计划发布 2.0 版本。与 Rust 本身不同,我们认为 Rustfmt 有一个破坏性发布是个好主意,并预计这将在 2019 年末的某个时候发生。
要安装 Rustfmt,请使用 rustup component add rustfmt
。要格式化您的项目,请使用 cargo fmt
。您还可以使用 rustfmt
格式化单个文件(但请注意,默认情况下 rustfmt 会格式化嵌套模块)。您还可以使用 RLS 在编辑器或 IDE 中使用 Rustfmt(参见下文;无需为此安装 rustfmt,它是 RLS 的一部分)。我们建议配置您的编辑器在保存时运行 rustfmt。在输入时完全不必考虑格式化是一种愉快的改变。
感谢 Seiichi Uchida (topecongiro)、Marcus Klaas 以及所有 Rustfmt 贡献者!
IDE 支持
对于许多用户来说,他们的 IDE 是最重要的工具。Rust IDE 支持已经开发了一段时间,这是一个高度需求的功能。现在许多 IDE 和编辑器都支持 Rust:IntelliJ、Visual Studio Code、Atom、Sublime Text、Eclipse(以及更多...)。点击每个链接查看安装说明。
编辑器支持有两种不同的方式:IntelliJ 使用自己的编译器,其他编辑器则通过 Rust 语言服务器 (RLS) 使用 Rust 编译器。这两种方法都能提供良好但不完美的 IDE 体验。您应该根据您偏好的编辑器来选择(尽管如果您的项目不使用 Cargo,您将无法使用 RLS)。
所有这些编辑器都支持标准的 IDE 功能,包括“转到定义”、“查找所有引用”、代码补全、重命名和重新格式化。
RLS 由 Rust 开发工具团队开发,旨在将 Rust 支持引入尽可能多的 IDE 和编辑器。它直接使用 Cargo 和 Rust 编译器来提供关于程序的准确信息。由于性能限制,代码补全尚未由编译器提供支持,因此可能不如其他功能那样精准可靠。
感谢 IDEs 和编辑器团队在 RLS 以及各种 IDE 和扩展方面的工作 (alexheretic, autozimu, jasonwilliams, LucasBullen, matklad, vlad20012, Xanewok),感谢 Jonathan Turner 帮助启动 RLS,以及 phildawes, kngwyu, jwilm 和其他 Racer 贡献者在 Racer (RLS 的代码补全组件)方面的工作!
未来
我们还没有完成!在接下来的大约一年时间里,我们认为我们可以在工具领域做更多的事情。
我们一直在改进 LLDB 和 GDB 中的 Rust 调试支持,并且还有更多工作正在进行中。我们正在尝试使用 Rustup 分发我们自己的版本,并使通过 IDE 进行调试变得更容易、更强大。
我们希望让 RLS 更快、更稳定、更准确;包括使用编译器进行代码补全。
我们希望让 Cargo 更加强大:Cargo 将处理编译后的二进制文件以及源代码,这将使构建和安装 crate 更快。我们将支持与其他构建系统更好地集成(这将反过来使 RLS 能用于更多项目)。我们将添加用于添加和升级依赖项以及帮助进行安全审计的命令。
Rustdoc 将改进其源代码视图(由 RLS 提供支持)以及不同 crate 文档之间的链接。
总是有很多有趣的事情可以做。如果您想帮忙,请在 GitHub 或 Discord 上与我们聊天。