Rust 官方文章《人们喜欢 Rust 的哪些方面?》
作者:Niko Matsakis 代表 Vision Doc Group
- 核心观点:Rust 的“魔法”源于平衡
文章指出,用户对 Rust 的热爱并非源于某个单一特性,而是可靠性、效率、控制感和工具链这几要素的“完美平衡”。
- 不可替代的组合:文章强调,如果拿掉任何一个要素,Rust 的吸引力就会坍塌。例如,没有了“效率”,Rust 进不去嵌入式领域;没有了“可靠性”,团队就不敢放手让初级工程师修改关键代码。
- 跨领域的“通行证”:Rust 让开发者敢于跨界。文中提到了几个真实的职业转型案例:从前端转入密码学研究、从 Java 开发者转入汽车嵌入式领域。这种“赋能感”是用户忠诚度的根源。
- 用户痛点:不仅仅是赞美
文章非常坦诚地讨论了目前 Rust 让开发者感到“痛苦”的地方:
- “意面类型”(Spaghetti Typing):虽然类型系统很强大,但当
async、泛型和生命周期结合时,类型会变得极其复杂,甚至连资深开发者也难以理解。 - 异步 Rust 的“忧伤深渊”(Chasm of Sadness):异步生态被认为尚未完全成熟。开发者提到了对
Pin的困惑、运行时的锁定问题(Tokio 依赖),以及在异步代码中难以调试 CPU 高占用的问题。 - “选择的暴政”(Tyranny of Choice):
crates.io虽然丰富,但新手很难在成千上万的库中找到“标准解”。比如,新手还在用Result<Box<dyn Error>>,而老手都在用anyhow。
- 三大战略建议(核心行动点)
为了保持 Rust 的竞争优势,文章代表 Vision Doc 小组提出了三项具体建议:
- 制定设计目标的 RFC(Goldilocks 原则):
- 明确 Rust 的设计目标(可靠、高效、支持性等)。
- 引入“金发姑娘(Goldilocks)”框架:描述每个特性在“太少”、“恰到好处”和“过度设计”时的表现,帮助后续开发保持在“恰到好处”的状态,避免过度复杂化。
- 加倍投入“可扩展性”:
- 让第三方库也能像编译器一样提供高质量的错误诊断和建议。
- 允许库在编译管道的不同阶段(如 Stable MIR、build-std)进行集成,以支持安全关键型系统或 GPU 编程等特定需求。
- 引导生态导航与互操作性:
- 打破 Rust 官方“中立”带来的迷茫,寻找不损害实验性的方式来“推荐”标准构建块(如
httpcrate)。 - 通过增加关键的互操作 Trait(特别是异步领域)来减少库与具体运行时的深度绑定。
- 打破 Rust 官方“中立”带来的迷茫,寻找不损害实验性的方式来“推荐”标准构建块(如
2025 年的 Rust 正处于从“因安全而流行”向“因全能且易用而持久”转型的关键点,官方正试图通过简化复杂度和增强生态引导来降低那个“忧伤深渊”的深度。
阅读:https://blog.rust-lang.org/2025/12/19/what-do-people-love-about-rust/
Coreutils 发布 0.5.0:已达到 87.75% 的 GNU 兼容性
uutils/coreutils 是一个用 Rust 重写 GNU coreutils 的项目。
1. 核心进展:GNU 兼容性提升
- 兼容度:目前已达到 87.75% 的 GNU 兼容性。
- 测试通过数:通过了 566 个 GNU 官方测试用例,比上一版本(0.4.0)增加了 22 个。
- 基准更新:测试基准已更新至 GNU Coreutils 9.9 版本(此前为 9.8)。
2. 主要工具改进
cksum:与hashsum合并,实现了统一的校验和功能。fold:增强了 Unicode 支持,添加了对“组合字符(combining character)”的处理,使文本换行更正确。install:增强了模式(mode)解析,现在支持逗号分隔的模式字符串以及umask处理。seq:改进了大整数的处理能力,并添加了专门的基准测试。ptx:实现了 GNU 模式以及 dumb terminal 格式支持。numfmt:进行了大量改进。
3. 平台支持扩展
- OpenBSD:正式加入 CI(持续集成)流程,通过了全面测试。
- Redox OS:在 CI 中重新启用了对 Redox 操作系统的支持。
- Cygwin:增强了在 Windows Cygwin 环境下的支持。
4. 开发者体验与性能
- 测试工具:新增了 TTY 辅助工具以增强测试能力。
- 依赖优化:通过特性拆分(feature splitting)减少了依赖膨胀。
- 性能:针对多个工具进行了内存和性能优化,并在 CI 中集成了 CodSpeed 以防止性能回退。
总结:0.5.0 版本是一个重要的里程碑,不仅在通过率上稳步提升,还解决了多个核心工具(如 cksum 和 fold)的关键功能缺失问题,同时扩展了对 OpenBSD 等操作系统的支持。
仓库:https://github.com/uutils/coreutils
文章《无需使用 RefCell 编写一个可模拟的 Filesystem trait》
作者分享了他在为智能合约模糊测试工具编写 CLI 时,如何重构文件系统(Filesystem)的 Mock 接口,以避免使用 RefCell 的经验。
1. 遇到的问题
- 背景:作者需要测试一个涉及大量读写磁盘操作的 CLI 工具。为了避免在测试中创建和清理临时文件,他决定在内存中 Mock 文件系统。
- 最初的尝试:
- 定义了一个
FilesystemTrait,其中的写入方法(如write_string)使用了&self(不可变引用)。 - 原因:对于真实的
RealFilesystem(基于std::fs),这没问题,因为其状态在操作系统层面,结构体本身是无状态的。 - 痛点:对于测试用的
TestFilesystem(基于HashMap),为了在&self方法中修改内部数据,不得不使用 内部可变性(Interior Mutability),即Rc<RefCell<HashMap<...>>>。 - 后果:代码变得混乱,到处是
clone(),且RefCell导致了“幽灵般的超距作用”(shared mutable state),即多个组件共享同一份数据,修改一方会隐式影响另一方,且类型系统无法反映出“这是一个会改变状态的操作”。
- 定义了一个
2. 解决方案
- 重构 Trait:作者决定让类型系统“诚实”地反映行为,将写入方法的签名改为接受
&mut self(可变引用)。fn write_string(&mut self, path: &Path, content: &str) -> ...
- 对真实实现的影响:对于
RealFilesystem,虽然它不需要可变性,但实现&mut self接口完全没有问题。 - 对 Mock 实现的影响:
TestFilesystem现在可以直接修改内部的HashMap,彻底抛弃了RefCell和Rc。
3. 收益
- 代码更清晰:去除了复杂的包装类型和不必要的 clone。
- 类型安全:利用 Rust 的借用检查器在编译时保证了逻辑的正确性。如果一个函数需要写入文件,它必须持有文件系统的可变引用,这使得副作用显式化。
- 总结:作者认为与其为了迁就无状态的真实实现而扭曲 Mock 实现(假装不可变),不如诚实地承认“写入即改变”,使用
&mut self是更符合 Rust 惯例(Idiomatic)的做法。
阅读:https://pyk.sh/blog/2025-12-15-writing-mockable-fs-in-rust-without-refcell
文章《Rust UI 框架中通过 Proc 宏实现位置 memoization》
这篇文章介绍了 Rust UI 框架 Tessera v3 中新引入的 remember 机制,旨在解决即时模式 GUI(Immediate Mode GUI)开发中的状态管理痛点。
- 解决的核心问题:
remember解决了必须将所有子组件状态“提升(Hoisting)”到父组件的旧模式,消除了由此引发的代码臃肿、繁琐的命名问题以及在不同渲染阶段传递数据时的“Clone Hell(克隆地狱)”。 - 功能特性:类似于 React 的
useState,它允许组件在内部跨帧持久化状态,但限制更少(可用于循环和条件判断中),并返回轻量级的State<T>句柄,无需手动克隆Arc。 - 实现原理:采用了**位置记忆(Positional Memoization)**技术,通过
#[tessera]过程宏重写代码中的控制流(如if,match),插入GroupGuard来精确追踪调用位置,这比使用#[track_caller]更稳定可靠。 - 当前限制:由于宏展开顺序的限制,
remember目前尚无法在声明式宏(Declarative Macros)内部正常工作。
阅读:https://tessera-ui.github.io/blog/positional-memoization-via-proc-macros.html
讨论:选择 Tokio 还是 Compio?
1. 最大痛点:生态系统的隔离 (The Ecosystem Gap) 这是所有评论中最一致的观点。
- Tokio 是事实标准:Rust 异步生态中绝大多数流行的库(如
reqwest,sqlx,axum,hyper等)都深度依赖 Tokio。 - 不兼容性:如果你使用 Compio,你无法直接使用上述这些库。你必须寻找 Compio 生态下的替代品(目前选择很少),或者使用兼容层(如果有的话,但通常会有性能损耗或 Bug)。
- 结论:除非你在构建一个几乎不依赖外部 IO 库的独立系统(如数据库存储引擎),否则“脱离 Tokio”会让你寸步难行。
2. 核心技术差异:Completion vs. Readiness
- Tokio (Readiness Based):基于
epoll(Linux) /kqueue(macOS)。模型是“告诉我什么时候可以读写,然后我自己去读写”。这是 Unix 的传统模型。 - Compio (Completion Based):基于
IOCP(Windows) 和io_uring(Linux)。模型是“把 Buffer 给操作系统,操作完成后叫醒我”。 - 影响:
- Windows 性能:Tokio 在 Windows 上的性能相对较差(因为它必须用兼容层模拟 Unix 行为),而 Compio 利用原生的 IOCP,在 Windows 上的 IO 性能理论上远超 Tokio。
- Linux 性能:对于极高吞吐量的场景,Compio 利用
io_uring也能提供比 Tokio 更高的上限。
3. API 设计的根本不同(Buffer 所有权)
- 这是对开发者影响最大的代码层面差异。
- Tokio 风格:
read(&mut buffer)。你传入一个引用,因为你在用户态同步读取。 - Compio 风格:必须转移 Buffer 的所有权给运行时。因为在 Completion 模型下,操作系统会在后台写入这个 Buffer,如果仅仅传引用,Rust 的借用检查器无法保证操作系统写入时该内存还活着。
- 结果:这意味着你不能使用标准的
AsyncRead/AsyncWritetrait,代码风格需要改变,导致现有代码复用困难。
4. 适用场景建议
- 不推荐:构建普通的 Web 服务、API 后端、CLI 工具(因为即使 Compio 快一点,缺乏生态会让开发成本无限拔高)。
- 推荐:
- Windows 优先的应用:如果你在开发高度依赖 IO 的 Windows 桌面软件或服务。
- 底层基础设施:如自行研发的数据库、存储系统,你不依赖 HTTP 客户端或 SQL 驱动,而是直接操作文件和 Socket,且追求极致的 IO 性能。
总结: 选择 Compio 意味着放弃现成的丰富生态以换取特定平台(特别是 Windows)和特定场景下的极致 IO 性能。对于 99% 的常规应用开发,Tokio 仍然是唯一理性的选择。
阅读:https://www.reddit.com/r/rust/comments/1pn6010/compio_instead_of_tokio_what_are_the_implications/
分享:使用 RMK 和 Embassy 的量产键盘背后的固件
作者:haobogu_ (RMK 作者)
1. 项目背景
- 产品:Elytra —— 一款超轻量级的无线分体式机械键盘。
- 里程碑:该键盘刚刚发布,其完整固件完全使用 Rust 编写。
- 技术栈:
- RMK:作者开发的 Rust 键盘固件库。
- Embassy:Rust 的现代异步嵌入式框架。
- Trouble:用于处理 BLE(低功耗蓝牙)连接。
2. 技术亮点与性能
- 低功耗:得益于 Rust 和 Embassy 的高效管理,键盘的外设端(Peripheral side)待机电流低于 20 µA,超出了作者的预期。
- 开发体验:调试过程非常顺畅,主要使用了
defmt(高效日志库)和probe-rs(调试工具)。 - 稳定性:前两批样品的固件运行非常稳定(Rock solid)。
3. 核心结论
- 作者通过这个商业项目证明:Rust 已经完全具备开发商业嵌入式产品的能力。
- 面对“为什么不用 C 语言”的质疑,作者认为在当今的生态下,使用 Rust 不再是一种妥协(Compromise),而是成熟的选择。
阅读:https://www.reddit.com/r/rust/comments/1pomzhb/shipping_embedded_rust_the_firmware_behind_a/
--
From 日报小组 苦瓜小仔
社区学习交流平台订阅:
评论区
写评论还没有评论