Rust 风格指南

Google 新发布的 Rust 风格指南引发了争论:当大型代码库越来越多地借助 AI 编写和审查时,面向人的严格约定是否仍然重要。许多评论者认为,一致的 API、crate 结构和模式(例如偏好枚举而不是布尔值、使用小 crate、明确区分所有权与 Rc/Arc)对于可读性、安全性和大型团队协作反而更重要——尤其是在 monorepo 和分布式系统中。讨论还扩展到 Rust 相对于 C 和 C++ 的角色、AI 辅助世界中的长期可维护性,以及今天应当多大程度上重视 Google 的工程规范。

风格指南在 LLM/“Agentic” 时代的作用

  • 有人认为风格指南不那么重要了,因为代码将由 LLM 生成,而且主要会通过 AI 解释来阅读,而不是被人直接阅读。
  • 也有人强烈反驳:
    • 风格对于可读性、长期维护和跨团队协作仍然很重要。
    • 无论代码由谁编写,一致的 API 和实现设计都很有价值。
    • 在“agentic”世界里,清晰的规则有助于人类有意义地审查和控制 AI 输出。
  • 还有少数人表示会把风格指南交给 LLM;模型并不总是会遵守,而如果没有强有力的权威或自动化 lint 工具,人工执行起来很困难。

Rust 与 C/C++ 以及未来

  • 争论的焦点是:新的 C/C++ 是否还在被编写:
    • 许多人说是的:国防、嵌入式、HPC、游戏、庞大的既有代码库,以及大型项目仍然大量使用 C/C++。
    • 其他人则声称 Rust 正在“吞噬” C/C++,尤其是在安全敏感和新的 greenfield 系统中,有些公司甚至“all in” Rust。
  • 反驳观点:
    • 各类生态(例如游戏开发)即便会迁移,也需要很多年。
    • 某些领域(极致性能、面向数据的设计)可能会觉得 Rust 的借用检查器在使用体验上比 C++ 更昂贵。
    • 有人认为 LLM 会让语言选择变得不那么重要,甚至会把 Rust 降级为一种中间表示。

争论中的具体风格规则

  • 枚举 vs 布尔值: 广受欢迎;枚举能缩小解释空间,避免令人困惑的标志位。
  • Rc/Arc vs 生命周期:
    • 一派:对于逃离栈的数据,随意使用 Rc/Arc;生命周期“很怪”。
    • 另一派:共享所有权会掩盖谁拥有什么;生命周期更清晰,Rc/Arc 应只保留给真正需要共享的场景。
  • Getter/setter 命名:
    • 指南偏好 getter 使用裸方法名,setter 使用 set_/builder 风格,这与 Rust stdlib/protos 保持一致。
    • 也有人更喜欢相反的方式,以便在 UI/TUI 的 builder 风格 API 中更流畅、更一致。
  • #[non_exhaustive] 枚举:
    • 批评者:破坏穷尽性检查,把编译期安全变成运行时 bug。
    • 支持者(尤其在“Google 规模”和分布式系统中):这是 API 演进所必需的,能避免跨很多团队的大规模破坏性变更;并可结合 lint 来标记遗漏的模式。

Google/Chromium 特定实践

  • 偏好很多小 crate,并避免深层模块嵌套:
    • 原因:构建更快、更易并行化;依赖更细粒度;配合 Blaze/Bazel 的缓存性更好(没有增量 crate 编译)。
  • 目前在 Chromium Rust 中不鼓励使用 async/await。
  • 强调区分库代码与应用代码,并强调那些可以在大型公司规模下统一适用的规则,即使它们对小项目来说并不总是“理想”。

工具与命名细节

  • rustfmt 已存在,但该指南涵盖的是更广泛的设计/风格问题。
  • 对以下内容也存在分歧:
    • 类型导入时使用未限定名称,还是为了清晰起见使用完全限定名称。
    • 十六进制字面量字母大小写(指南偏好小写)以及其他一些可读性上的小调整。