2018 版工具

2018 年 12 月 17 日 · 开发工具团队

工具是使编程语言实用和高效的重要组成部分。Rust 一直拥有很棒的工具(特别是 Cargo 作为一流的包管理器和构建工具,享有盛誉),2018 版包含更多工具,我们希望这些工具能进一步改善 Rust 用户的体验。

在这篇博文中,我将介绍 Clippy 和 Rustfmt - 这两种工具已经存在几年了,现在已经稳定并准备投入使用。我还将介绍 IDE 支持 - 这是许多用户的关键工作流程,现在得到了更好的支持。我将从介绍 Rustfix 开始,这是一个新的工具,它是我们版本迁移计划的核心。

Rustfix

Rustfix 是一个用于自动更改 Rust 代码的工具。它是我们 2018 版迁移故事的关键部分,使从 2015 版到 2018 版的过渡变得更加容易,在许多情况下,过渡是完全自动的。这是至关重要的,因为如果没有这样的工具,我们对用户接受的重大更改类型将更加有限。

一个简单的例子

trait Foo {
    fn foo(&self, i32);
}

上面的代码在 Rust 2015 中是合法的,但在 Rust 2018 中则不是(方法参数必须明确)。Rustfix 将上面的代码更改为

trait Foo {
    fn foo(&self, _: i32);
}

有关如何使用 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。它有许多(目前有 290 个!)lint 来帮助提高程序的正确性、性能和样式。每个 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 中应用 Clippy 的建议(或使用 Rustfix),并且 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 中运行它,请参阅 仓库自述文件

感谢 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 版发布。向后兼容意味着,如果您的代码已格式化(即,不包括阻止任何格式化或无法编译的代码的错误),它将始终以相同的方式格式化。此保证仅适用于使用默认格式化选项的情况。

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 支持已经开发了一段时间,并且是一个高度需求的功能。Rust 现在在许多 IDE 和编辑器中得到支持:IntelliJVisual Studio CodeAtomSublime TextEclipse(等等)。请按照每个链接中的说明进行安装。

编辑器支持通过两种不同的方式实现:IntelliJ 使用它自己的编译器,其他编辑器通过 Rust 语言服务器 (RLS) 使用 Rust 编译器。这两种方法都提供了良好但并不完美的 IDE 体验。您应该根据您喜欢的编辑器进行选择(尽管如果您的项目不使用 Cargo,那么您将无法使用 RLS)。

所有这些编辑器都支持标准的 IDE 功能,包括“转到定义”、“查找所有引用”、“代码完成”、“重命名”和“重新格式化”。

RLS 由 Rust 开发工具团队开发,旨在将 Rust 支持带到尽可能多的 IDE 和编辑器中。它直接使用 Cargo 和 Rust 编译器来提供有关程序的准确信息。由于性能限制,代码完成尚未由编译器提供支持,因此可能比其他功能更不稳定。

感谢 IDE 和编辑器团队为 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 上与我们聊天。