<rss version="2.0"><channel><title>Rust.cc</title><link>https://rust.cc</link><description>This Is Rust Crustacean Community RSS feed.</description><item><title>【Rust日报】2026-10-22 有张中间证书私钥是数字 4</title><link>https://rustcc.cn/article?id=c4441ed0-d537-4e05-8990-f1ccc4802a40</link><description><![CDATA[<h2>有张中间证书私钥是数字 4</h2>
<p>https://emudhra.we-have-a-problem.com/ 是一份说明 eMudhra 中间 CA 证书私钥问题的页面，页首日期是 2026 年 10 月 20 日。作者 noop_noob 2026 年 10 月 21 日把它发到 r/rust，采集时 645 分、109 条评论。</p>
<p>页面写，8 张 eMudhra 中间 CA 证书的私钥已经泄露。这些证书链到 Mozilla、Microsoft、Apple 和 Chrome 根程序信任的根，也进入许多下游信任库。报告人 Wayne 在 2026 年 10 月 17 日用每张中间证书的私钥对消息 “We have a problem here - Wayne” 做了签名，并报告给各根程序团队。Mozilla Bug 2083449 写，Mozilla 于 2026 年 10 月 17 日 20:06 UTC 收到这份报告，报告同时通知了 eMudhra 以及 Apple、Microsoft 根程序，并附有 8 张证书的密钥控制证明。</p>
<p>页面写，这些中间证书的私钥生成方式有误，任何人都可以从证书里还原。证书创建于 2025 年 4 月。页面写，那段时间这些中间证书没有证书透明度日志记录，因此 Firefox、Chrome、Edge、Safari 这类强制执行 CT 的客户端当时无法被这种密钥用来攻击。页面同时写，不少浏览器以外的客户端不强制 CT，目前不知道攻击者是否已经用这个缺陷打过这些客户端。</p>
<p>Ars Technica 写，这些私钥的熵只有 3 到 8 位，列出的私钥整数是 4、56、66、115、155、156、230、237。文章写，正常的 NIST P-384 椭圆曲线私钥大约有 384 位熵。Go 加密维护者 Filippo Valsorda 对 Ars 说，这次清理会是一项大规模工作，比 Heartbleed 更大，长尾包括物联网设备、Docker 容器、遗忘的 Linux 机器，以及自带根证书副本的命令行工具。</p>
<p>页面写，Firefox 和 Chrome 从 2026 年 10 月 17 日起屏蔽这些证书，Apple 设备从 10 月 19 日起，Microsoft 平台从 10 月 20 日起。CA 也已经吊销这些中间证书。页面写，许多不读取吊销信息的客户端需要软件更新。</p>
<p>Rust 侧的修复版本写在同一页面和 RustSec 上。RUSTSEC-2026-0382 的包是 rustls-webpki，别名 CVE-2026-111943。公告写，受影响版本在信任锚允许时，可能接受包含这些已不受信任 emSign 中间公钥的证书路径；0.103.16 和 0.104.0-alpha.8 会拒绝这些公钥。页面列出的 webpki-roots / webpki-root-certs 修复版本是 1.0.10。rustup 1.29.2 只更新 rustls-webpki 和 webpki-root-certs，用来处理同一问题。已安装 rustup 时，可以执行 <code>rustup self update</code>；普通的 <code>rustup update</code> 结束时也会自动更新 rustup。r/rust 帖子写，reqwest 依赖这些 crate。同一事件的 rustup 发布帖不再单列。</p>
<p>评论里 AliceCode（431 分）问，他们把整个密钥做成数字 4 了吗。作者 noop_noob（145 分）回复，不知道还能说什么。</p>
<p>原文链接：https://emudhra.we-have-a-problem.com/</p>
<h2>Linux 7.4 将合入约 1.7 万行 Rust</h2>
<p>Phoronix 2026 年 10 月 20 日的这篇报道写的是准备进入 Linux 7.4 的 Rust 内核代码拉取请求。作者 Fcking_Chuck 2026 年 10 月 21 日把它发到 r/rust，采集时 324 分、31 条评论。</p>
<p>报道写，Miguel Ojeda 发出了这次拉取请求。增量大约 1.7 万行，主要因为 vendored 的 Zerocopy 一次跳了 8 个版本，同时更新了内核里的其他 Rust crate。Zerocopy 提供 trait 和宏，用来在原始字节序列和结构化类型之间做安全转换。报道还写，这次启用不稳定特性 proc_macro_span，用来改善所有过程宏的诊断。内核 Rust crate 新增 mem 和 ratelimit 模块。pin-init 增加元组结构体支持，并允许安全创建自引用，诊断也有改进。拉取请求在 https://lore.kernel.org/lkml/20261018163459.80579-1-ojeda@kernel.org/ 。报道写，子系统自己的拉取请求里还会有更多 Rust 代码，包括 NVIDIA Nova 驱动改进和其他 Rust DRM 基础设施。</p>
<p>评论里 moltonel（69 分）写，从 v7.3 起目前看起来新增约 2.9 万行，合计约 22 万行，大约占内核代码的 0.5%。其中约 8.1 万行来自 vendored crate，包括 syn、zerocopy、proc-macro2。从 v6.2 起，平均每个版本增长约 17%。同帖里有人问 vendored crate 是什么。bleachisback（15 分）回复，这是把第三方依赖的源码放进自己的项目，不通过 Cargo.toml 正常依赖。</p>
<p>原文链接：https://www.phoronix.com/news/Linux-7.4-Rust</p>
<h2>Google 公开内部 Rust 风格指南</h2>
<p>https://google.github.io/styleguide/rustguide.html 是 Google 内部使用 Rust 的风格指南。作者 Western-Obligation47 2026 年 10 月 21 日把讨论转到 r/rust，采集时 16 分、6 条评论。原帖在 r/learnrust，页面显示 44 分、20 条评论。</p>
<p>指南写，这里的 style 同时包括格式、API 设计和实现设计。文中列出的使用场景有 google3、Android、ChromeOS、Fuchsia 和 Chrome。适用范围一节写，Android、Chromium 和其他代码库参与了咨询，并打算开始采用；各代码库可以自己规定执行松紧。目标一节写，Large-Scale Changes 在 Google 很常见，风格一致是为了让这类跨代码库修改更容易做。</p>
<p>几条和常见开源仓库不同的规则：</p>
<ul>
<li><code>rust_library</code> 的源文件放在同一个目录。指南写，不要用子目录组织同一个 crate 的文件。如果需要子目录，通常说明这个 crate 已经太大，应该拆开。用 Cargo 构建的 <code>//third_party</code> 代码除外，仍按常规 Cargo 目录。</li>
<li>不要使用 glob import。例外包括 inline module 的 <code>use super::*</code>、主要处理某个 enum 时在函数体里写 <code>use enum::*</code>、非叶子模块的 <code>pub use submodule::*</code>，以及为合并 C++ namespace 而做的 glob import。</li>
<li>避免 <code>Rc</code> 和 <code>Arc</code>。指南写，Rust 通常可以不用共享所有权智能指针表示对象图；从其他语言过来的工程师容易过早使用它们。</li>
<li>Chromium 里不要使用 <code>async</code> / <code>.await</code>。Chromium 里也不要通过 Rust 标准库新建线程，优先使用 sequence。</li>
<li>库代码的 API 设计规则是强制的。应用代码里，这些规则是强建议，写法偏向简单直接，少做广泛复用。</li>
<li>不要仅仅为了组织代码而定义 trait。</li>
<li>指南写，要完全避免 panic，即使不变量被破坏也用 <code>Result</code> 报告。例外是面向开发者的二进制可以把非致命错误做成 panic，测试可以用 panic 做断言。</li>
<li>如果类型系统表达不了不变量、必须 panic，用 <code>expect</code> 写明原因。指南不使用 <code>unwrap</code>。</li>
<li>不要调用 <code>panic::catch_unwind</code>。</li>
</ul>
<p>原文链接：https://google.github.io/styleguide/rustguide.html</p>
<h2>Tyr 在 Linux 7.3 启动 Mali 固件</h2>
<p>Tyr 是 Arm Mali-G610 的 Linux 内核 GPU 驱动，用 Rust 移植已有的 C 驱动 Panthor，对用户空间保持透明。这颗 GPU 使用 Valhall v10，通过 Command Stream Frontend 和内核驱动通信。Collabora 的 Deb Brouwer 2026 年 10 月 21 日发文介绍上游进展。作者 mfilion 同日把它发到 r/rust，采集时 55 分、1 条评论。mfilion 写自己在 Collabora，Tyr 在那里开发。</p>
<p>文章写，Tyr 的初始 stub 在 2025 年 11 月合入 Linux v6.18，当时可以探测、绑定、上电、查询硬件信息并关机。v7.3 合入的提交让 Tyr 可以启动 GPU 的 MCU，从而和 GPU 通信。为此需要虚拟地址空间、映射方法，以及可靠配置 GPU 的 MMU。Tyr 依赖三组 Rust 抽象：DRM GEM 共享内存 helper、页表管理、GPUVM。</p>
<p>MCU 固件是二进制镜像，来自 Linux firmware 仓库或发行版包。Rust 已有 Linux firmware request API 的抽象，把固件载入系统内存这一步比较直接。GPU 还要求固件放在 DRM 的 GEM 缓冲区里。基础 GEM 抽象由 Asahi Lina 编写，不含后备内存的实现在 2025 年 7 月合入 Linux v6.16。Lyude Paul 和 Danilo Krummrich 在 2026 年 6 月把共享内存 helper 合入 Linux v7.1。页表抽象最初由 Asahi Lina 编写，Alice Ryhl 做了大幅重写，2026 年 4 月合入 Linux v7.0。</p>
<p>文章写，上游 Tyr 目前大约 3700 行，其中 6 行使用 unsafe，3 行和页表抽象有关。页表抽象的 <code>map_pages()</code> 是 unsafe，文档里的 Safety 要求写明调用方必须满足的条件。文章写，即使固件布局简单且固定，Tyr 仍使用完整的 GPUVM，用来维持这些不变量。文章写，这些不变量不能只靠假设。</p>
<p>原文链接：https://www.collabora.com/news-and-blog/blog/2026/10/21/upstreaming-tyr-rust-drm-and-the-linux-kernel/</p>
<hr>
<p>From Rust中文社区 Mike</p>
<p>社区学习交流平台订阅：</p>
<ul>
<li><a href="https://rustcc.cn/" rel="noopener noreferrer">Rustcc论坛: 支持rss</a></li>
<li><a href="https://rustcc.cn/article?id=ed7c9379-d681-47cb-9532-0db97d883f62" rel="noopener noreferrer">微信公众号：Rust语言中文社区</a></li>
</ul>
]]></description><pubDate>2026-10-22 01:07:34</pubDate></item><item><title>【Rust日报】2026-10-21 Cloudflare 用 Rust 移植 TypeScript</title><link>https://rustcc.cn/article?id=13d7c53f-3d2b-4d61-b760-bc7aa2346f20</link><description><![CDATA[<h2>Cloudflare 用 Rust 移植 TypeScript</h2>
<p>tsrs 是 TypeScript 7 类型检查器的 Rust 移植，仓库在 https://github.com/oxc-project/tsrs ，许可证 Apache-2.0。Cloudflare 2026 年 10 月 20 日发文介绍。Taymon 同日把它发到 r/rust，采集时 98 分、63 条评论。采集时 GitHub 有 1090 个 star，最近推送时间是 2026 年 10 月 21 日。</p>
<p>文章写，Cloudflare、VoidZero 和 Owner.com 的 Max Schwenk 一起做这个移植，并和 TypeScript 团队合作。项目放在 Oxc 工具链里孵化。文章写，语言设计和方向仍由 TypeScript 团队决定，tsrs 按上游实现保持兼容。</p>
<p>文章写，类型检查 worker 数量相同时，tsrs 比 TypeScript 7.0 最多快 8 倍，内存大约少 70%。文章写，TypeScript 7.1 beta 比 TypeScript 7.0 最多快 2.5 倍，其中一部分优化从 tsrs 回到了上游。仓库 <code>bench/RESULTS.md</code> 的 <code>--checkers 4</code> 表让两边都用 4 个 checker 线程，对照 typescript@7.0.2 和更后面的 7.1-dev 移植。这张表里 mui-docs 是 12.69 秒对 1.07 秒，vscode 是 10.94 秒对 2.21 秒。机器是 Depot CI 的 16 vCPU。仓库写，tsrs 移植的提交晚于 7.0.2，部分项目的报错条数不同，是因为中间 TypeScript 本身有变化。</p>
<p>安装命令是 <code>npm install tsrs</code>，然后 <code>npx tsrs</code>。仓库写，当前对齐 microsoft/TypeScript 主分支，稳定版目标是 TypeScript 7.1 上的完全一致。<code>--init</code> 和 <code>--showConfig</code> 还不支持。诊断输出顺序和上游还有差别。WebAssembly 包是 <code>@tsrs/wasm</code>，目标 wasm32-wasip1。浏览器 playground 在 https://tsrs-playground.void.app 。</p>
<p>文章写，接下来会和 Theo Browne 把 tsc-rs 并进 tsrs，仓库在 https://github.com/pingdotgg/ts-rust ，用来补上 LSP。维护方式比照 Vinext，用代理对照上游差异。性能改进会尝试回馈 TypeScript 的 Go 实现。</p>
<p>评论里 Taymon（31 分）写，项目由外部发起，现已交给 VoidZero，放进 oxc，目标是行为和上游 TypeScript 一致。Taymon（15 分）写，内部 arena 把分配出的引用标成 <code>'static</code>，接口没有标 <code>unsafe</code>。</p>
<p>原文链接：https://blog.cloudflare.com/typescript-rust-port/</p>
<h2>Rust UI 布局库对照表</h2>
<p>Are we layout yet? 是一个对照 Rust UI 布局库功能和性能的网站，地址是 https://arewelayoutyet.mespin.me/ ，源码在 https://github.com/marc2332/arewelayoutyet 。作者 mkenzo_8 2026 年 10 月 20 日把它发到 r/rust，采集时 56 分、15 条评论。作者也是 Torin 的作者。站点基准生成日期是 2026 年 10 月 20 日（UTC）。采集时仓库有 2 个 star，最近推送时间是 2026 年 10 月 20 日。</p>
<p>站点列入 Taffy、Morphorm、Torin、yoga-rs、ui-layout、clay-rs、Ply、Backer。功能对照包括布局模型、换行、尺寸、间距、约束、宽高比、自定义内容测量和像素网格取整。性能部分用从 Taffy 基准改来的 PanGUI 负载，每天跑一次。README 写，不同引擎的布局语义不同，缺结果表示适配器翻不过那个负载，计时不表示输出等价，也不表示总排名。文本测量目前不在对照里。</p>
<p>评论里 nicoburns（7 分）写，这组对比里 Taffy 最慢，但仍比驱动 React Native 的 Yoga 快。作者回复，Taffy 是这组里最快的 CSS 兼容布局库。另一条评论建议加入 backer，作者回复已经加上。</p>
<p>原文链接：https://arewelayoutyet.mespin.me/</p>
<h2>Rusteerio 把 Cheerio 移植到 Rust</h2>
<p>Rusteerio 是 Cheerio 的 Rust 移植，做成 JavaScript 侧的直接替换，仓库在 https://github.com/context-dot-dev/rusteerio ，许可证 MIT。Context.dev 发文介绍。TerrificMist 2026 年 10 月 21 日把它发到 r/rust，采集时 14 分、0 条评论。采集时 GitHub 有 36 个 star，仓库创建和最近推送都在 2026 年 10 月 16 日。</p>
<p>文章写，解析、选择器、修改和序列化在 Rust 里跑，JavaScript API 保持不变，目标行为是 Cheerio 1.2.0。兼容测试通过全部 777 个上游 Cheerio 测试，没有改原来的断言和夹具，也没有新增跳过。文章写，这次移植在一天以内完成，LLM 花费大约 1000 美元。</p>
<p>一组基准在 1 个 CPU 上解析并抽取 3000 个 Common Crawl 页面。三次 Linux 虚拟机的中位数：Rusteerio 1.1.6 每秒 364 页，Cheerio 1.2.0 每秒 92 页。机器是 AMD Ryzen 9 9950X，16 vCPU，32 GB 内存，Ubuntu 24.04，Node 24.18.1，测试钉在 1 个 CPU。另一组 5000 页流水线做解析、抽元数据和链接、遍历 DOM、去掉 script 和 style，再返回文本和序列化 HTML。Cheerio 用了 22.5 秒，Rusteerio 用了 10.2 秒。这组用 8 vCPU、16 GB 内存，同样不含网络抓取。文章写当前版本是 2.0.0，上面两组数字对应的是文中列出的 1.1.6。</p>
<p>安装命令是 <code>npm install rusteerio</code>。需要 Node.js 20.19 或更新。预编译二进制覆盖 macOS、Linux 和 Windows。</p>
<p>原文链接：https://www.context.dev/blog/introducing-rusteerio</p>
<h2>Par 加上 SQL、WebSocket 和自动清理</h2>
<p>Par 是用 Rust 实现的实验性并发编程语言，仓库在 https://github.com/par-team/par-lang ，许可证 MIT，网站是 https://par.run/ 。作者 faiface 2026 年 10 月 20 日在 r/rust 写了大约半年的更新，采集时 15 分、11 条评论。采集时 GitHub 有 808 个 star，最近推送时间是 2026 年 10 月 19 日。</p>
<p>标准库新增 Sql 和 WebSocket。Sql 覆盖 PostgreSQL、MySQL 和 SQLite，包括内存库、事务和行解码。WebSocket 同时有服务端和客户端。自动清理允许在类型上标出线性值被丢弃时要调用的方法。<code>Bytes.Writer</code> 的 <code>.close</code> 分支带 <code>*</code>，未使用时按 <code>.close</code> 丢弃。</p>
<p>三个大例子都是带网页的 HTTP 服务，目录在 https://github.com/par-team/par-lang/tree/main/examples 。Chat 用 WebSocket 做单房间聊天。Downloader 把文件下到本机并显示进度，多个文件可以同时下，也可以取消。Tasks 把待办存在 SQLite。</p>
<p>作者写，自己的非正式测试里，I/O 密集应用大约比半年前快 3 倍，计算密集大约快 6 倍，还没有严格基准。作者还写，私有测试里大约到 Python 3.12 的水平，不含 Python 里用 C 写的函数和库。其他更新包括 <code>@core/Time</code>、<code>@core</code> 里 120 多个新函数、编译期 <code>include("file.txt")</code>、<code>todo</code> 类型洞，以及 <code>.</code> 补全。</p>
<p>评论里 Shnatsel（2 分）写，Rust 的 Writer 在 Drop 时隐式 flush，失败时错误会丢掉。作者回复，Par 里可以手动 close，那时能拿到错误。</p>
<p>原文链接：https://www.reddit.com/r/rust/comments/1xax7w7/par_lang_update_3_big_examples_autocleanup_sql/</p>
<hr>
<p>From Rust中文社区 Mike</p>
<p>社区学习交流平台订阅：</p>
<ul>
<li><a href="https://rustcc.cn/" rel="noopener noreferrer">Rustcc论坛: 支持rss</a></li>
<li><a href="https://rustcc.cn/article?id=ed7c9379-d681-47cb-9532-0db97d883f62" rel="noopener noreferrer">微信公众号：Rust语言中文社区</a></li>
</ul>
]]></description><pubDate>2026-10-21 01:06:25</pubDate></item><item><title>【Rust日报】2026-10-20 一张图列出 20 个 Rust 数据库项目</title><link>https://rustcc.cn/article?id=e9c60079-2923-47d5-a804-4cfcef87447e</link><description><![CDATA[<h2>一张图列出 20 个 Rust 数据库项目</h2>
<p>这是一张把 20 个数据库项目围在 Rust 标志周围的图。Low_Brilliant_2597 2026 年 10 月 19 日把它发到 r/rust。采集时 722 分、143 条评论。帖子没有外部文章，原文就是这张图。</p>
<p>图的标题是 The Growing Ecosystem of Database Systems，副标题是 Built on Rust。中间是一个带 R 的齿轮。20 个项目标志用灰线连到中间。RisingWave 单独放在白底圆角框里。图上没有数字，也没有分类标注。</p>
<p>上排从左到右：Apache DataFusion、Neon、RisingWave、GreptimeDB、SurrealDB。左侧从上到下：Polars、ParadeDB、HelixDB、LanceDB、Qdrant。右侧从上到下：slatedb、Databend、turbopuffer、Turso、TiKV。下排从左到右：SmithDB、HydraDB、readyset、SedonaDB、influxdb。</p>
<p>评论里 dgkimpton（342 分）写，自己会继续用 Postgres，除非某个具体场景逼着换；要紧的是可靠性。TheLexoPlexx（167 分）写，图上这些项目都在卖托管云，功能比自托管版多；Postgres 就是 Postgres，再加上插件。mark-haus（61 分）写，Postgres 覆盖面广，本地连接、少运维可以看 SQLite，多数项目可以先从这两个开始。Hunter_Affectionate（18 分）写，图上列出的库面向 OLAP 或向量检索，举的例子是 Qdrant，并认为拿它们和 Postgres 比类别不同。f311a（28 分）写，它们各自对着具体场景，并不和 Postgres 竞争。Floppie7th（30 分）写，有选项这件事本身算不上麻烦。</p>
<p>原文链接：https://www.reddit.com/r/rust/comments/1x9rg9l/the_growing_ecosystem_of_rustbased_database/</p>
<h2>Rust 编译器多项长期投入开始见到结果</h2>
<p>这是一篇 Rust 编译器年度盘点。panstromek 2026 年 10 月 19 日把它发到 r/rust。采集时 208 分、6 条评论。文章末尾给出 GitHub Sponsors：https://github.com/sponsors/panstromek 。</p>
<p>文章写，多项长期投入在 2026 年同时走到后面的阶段，并开始看到结果。作者写，这一年的工作量本身并不比往年更大。</p>
<p>作者把下一代 trait solver 放在第一位。文章写，它重写类型系统的一大块，各种形式加起来接近 10 年，修一批健全性错误，并解开 async Rust 和 impl Trait 上的一批长期限制。Polonius 是另一项借用检查实现，能让更多代码通过编译。文章写，它还可能解开内部引用，时间不确定；对编译器的影响小于新 solver。</p>
<p>性能方面，并行前端接近稳定，项目目标由 petrochenkov 推进。停了几年后重新开始，SparrowLi 先加入，后来又有其他人。作者写，自己的感觉是几乎没有人真正满意这个设计，眼下也没有更好的替代，所以是把具体问题磨完。LLVM 23 的性能变化是明确正向。LLVM 10 升级曾经带来大约 10% 回退。LLVM 22 在 icount 上是绿的，wall time 上几乎全是红的。文章写，LLVM 23 基本全是正向。</p>
<p>Amanieu 提议的 MIR move elimination 去掉 LLVM 难以优化的拷贝，编译时间和运行时间都会变快。文章写，这一步放在 MIR，因为 Rust 侧知道这次消除对 Rust 是否合法，而且需要改一点 MIR 语义。Rust 生成的 move 比 C 和 C++ 多。camelid 推进的 polymorphization 仍是实验。文章写，原先的做法只避免重复单态化；这一次受 Swift 启发，把泛型参数的布局当参数传下去，有运行时成本，可以用编译器旗标调节。</p>
<p>blyxyas 在做 cargo check 和 cargo build 共享产物。文章写，这件事已经宣布，target 目录体积会缩小 5% 到 30%，看工作负载。新的 cargo build-dir 布局也已宣布，文章写它解开 target 目录的细粒度锁和跨 workspace 缓存。bjorn3 在修 no-link 和 link-only，用来把 build script 和 proc macro 流水线化。</p>
<p>架构上，jdonszelmann 两年前开始统一属性的表示和检查，文章写几天前最后一个属性迁到新系统。Zalathar 和 nnethercote 清理了 query system 的实现。项目目标方面，文章写现在有 Fast Builds 路线图。Maintainers in Residence 于 2026 年 8 月 26 日宣布。作者还写到 Hexcat 过去一年雇了一批人。作者自己加入过 perf triage，申请了 MiR，并同意在有资金时做 target 目录体积缩减。作者写，MiR 资金有限，自己不认为很快能排上。</p>
<p>评论里 termhn（16 分）写，自己平时跟得比较紧，文章里大约一半之前不知道。kibwen（8 分）写，这是一份清楚的总览。</p>
<p>原文链接：https://yoyo-code.com/2026-is-exciting-year-for-rust-compiler-and-me/</p>
<h2>Ante 用 place 做零成本循环可变</h2>
<p>这是 Ante 的一篇借用检查文章，讲如何用 place 做零成本的循环可变。RndmPrsn11 2026 年 10 月 19 日把它发到 r/rust。采集时 84 分、17 条评论。文章日期是 2026 年 10 月 19 日。</p>
<p>Ante 是带所有权和借用的低层函数式语言，仓库在 https://github.com/jfecher/ante ，许可证 MIT。采集时 GitHub 有 2357 个 star，最近推送时间是 2026 年 10 月 19 日。文章写，Ante 想放宽“可以别名，或者可以修改，不能同时”这条规则，同时仍静态拒绝悬垂指针。新设计把 group borrowing 和作者自己的想法合在一起。</p>
<p>文章用 place 代替 lifetime。place 是引用可能借自的那一组具体位置，可以是变量、字段路径，或几个来源的并集。不稳定的 place 写成 <code>!</code>。对 <code>a!</code> 的引用会在修改 <code>a</code> 时失效。<code>Vec.first_mut</code> 和 <code>Vec.last_mut</code> 返回 <code>mut 'v! t</code>。文章写，这样可以同时拿出第一个和最后一个元素再改其中一个，因为这次修改只会使 <code>v!!</code> 失效，而这两个引用的 place 是 <code>v!</code>。</p>
<p>循环可变用带 place 参数的 <code>Rc 'p t</code>。<code>Rc.get</code> 返回的内部引用同时带上外层不稳定 place 和共享 place。文章给出一个把链表尾指回前面节点的例子，遍历 5 步会交替打出 true 和 false。文章写，这和 Rust 里的 GhostCell 类似，检查全是静态的，不需要 GhostToken，也没有运行时检查。脚注写，用 Rc 组成循环仍然会泄漏，回收是另一件事。上一版设计在遍历时要克隆一些 Rc；文章写，新设计不再需要这些克隆。</p>
<p>线程安全沿用 Send 和 Sync。<code>ref</code> 和 <code>mut</code> 允许共享可变，两个 trait 都不实现。<code>imm</code> 和 <code>uniq</code> 对应 Rust 的 <code>&amp;</code> 和 <code>&amp;mut</code>。文章写，这两种引用很少用，主要出现在跨线程之后再降回 <code>ref</code> / <code>mut</code>。</p>
<p>评论里 Accomplished_Item_86（26 分）写，Valen 的 group borrowing、Mojo 和 Zeta 也在用一组可能来源跟踪失效或不相交，Ante 把这组来源叫 place。RndmPrsn11（15 分）回复，Carbon 也在往这个方向走。panstromek（9 分）问，新的部分到底是什么，因为 Polonius 已经在用接近 place 的模型。作者回复，自己原先以为把 lifetime 做成 place 是 Polonius 之外的工作，回头看原来的 Polonius 文章后认为这个判断不对；文章的主要部分仍是零成本循环可变。</p>
<p>原文链接：https://antelang.org/blog/safe_cyclic_mutability/</p>
<h2>mbrotli 把压缩任务交回调用方</h2>
<p>这是 Brotli 压缩库 mbrotli 的一篇设计说明，讲库如何把并行任务交回调用方。Mnwamnowich 2026 年 10 月 19 日发在 r/rust。采集时 47 分、26 条评论。</p>
<p>mbrotli 是安全 Rust 写的 Brotli 压缩库，仓库在 https://github.com/M-Compressors/mbrotli ，许可证 Apache-2.0。采集时 GitHub 有 21 个 star，最近推送时间是 2026 年 10 月 19 日。crates.io 当前版本是 0.5.16，总下载 1615 次。crate 说明写，编码结果与 Google 参考编码器逐字节相同，覆盖 RFC 7932 和 RFC 9841。</p>
<p>帖子写，库知道怎么把压缩拆开，执行交给调用方。<code>ParallelCompressor::writer</code> 返回写入端和任务队列。例子用 <code>std::thread::scope</code> 起 4 个线程，每个线程从队列里取任务并调用 <code>task.run()</code>。库自己不起线程。调用方要保证任务真的被执行。作者写，调度器设计得不好时容易死锁。作者写，低层库把调度权交出去，对已经有线程池的程序更合适；也写了，有些库自己管线程仍然合理。</p>
<p>评论里 aelgorn（27 分）写，库如果把并行能力暴露给调用方，调用方就能避开和硬件或场景不匹配的假设。作者（8 分）写，项目里常常已经有 rayon 或 tokio 的 <code>spawn_blocking</code>，库再起一套线程会碍事。flareflo（4 分）建议提供兼容 rayon 的迭代器，让调用方自己选择是否并行。</p>
<p>原文链接：https://www.reddit.com/r/rust/comments/1x9u5vw/some_thoughts_on_parallelism_in_libraries_who/</p>
<hr>
<p>From Rust中文社区 Mike</p>
<p>社区学习交流平台订阅：</p>
<ul>
<li><a href="https://rustcc.cn/" rel="noopener noreferrer">Rustcc论坛: 支持rss</a></li>
<li><a href="https://rustcc.cn/article?id=ed7c9379-d681-47cb-9532-0db97d883f62" rel="noopener noreferrer">微信公众号：Rust语言中文社区</a></li>
</ul>
]]></description><pubDate>2026-10-20 01:06:58</pubDate></item><item><title>【Rust日报】2026-10-19 借用检查可以倒着做</title><link>https://rustcc.cn/article?id=4295b6e8-3777-402b-97da-04a42b6f5f59</link><description><![CDATA[<h2>借用检查可以倒着做</h2>
<p>这是 verdagon 2026 年 10 月 18 日发在 r/rust 的文章，讲 Valen 编译器里一种从函数末尾往回走的安全检查。采集时 67 分、21 条评论。文章日期是 2026 年 10 月 18 日。</p>
<p>Valen 是实验性编程语言的编译器，仓库在 https://github.com/valen-lang/valen ，许可证 Apache-2.0。采集时 GitHub 有 586 个 star，最近推送时间是 2026 年 10 月 18 日。作者写，v0.1 预计在 2 月前后。文章写，这篇文字 0% 由 AI 写成。</p>
<p>文章写，编译一个函数分四步：解析成 AST，静态类型，静态分组，安全检查。静态分组记下每个引用指向哪个变量、或变量的哪一段。安全检查确认引用在失效之后还有没有被使用。这一步从函数最后一条语句往前扫到函数开头。作者写，据他所知，这是把内存安全检查本身做成反向扫描的借用检查器。文章对照了 rustc：NLL 和目前的 Polonius 先做 region 约束求解，再向前检查冲突。rustc 会向后扫描，用来确定变量用到哪里，内存安全检查仍向前走。Vale，以及 Valen 的上一版，也是先确定 region 或 group，再向前检查。</p>
<p>反向扫描维护一个 pending 列表。遇到 USE，把变量放进 pending。遇到 MUTATE，检查 pending 里有没有被这次修改失效的变量。遇到 DECLARE，把变量从 pending 里拿掉。文章用 <code>add_buff</code> 修改 <code>Entity</code> 之后仍使用指向 <code>buffs</code> 的引用，作为 use-after-free 的例子。作者给出的反向理由有三条：少一次先记下最后使用位置再跳回去的查找，循环里更容易判断引用有没有被重新赋值，以及每个节点在分组阶段和检查阶段各处理一次。作者写，速度这一点还没有做过基准测试。循环还要额外记录 <code>mutations_after_this</code> 和 <code>revived_after_this</code>。</p>
<p>评论里 Zde-G（27 分）写，更意外的是 rustc 的借用检查向前走，因为很多编译优化本来就是从 use 走到 def。verdagon（11 分）回复，反向扫描在编译器里常见，他 2024 年的 LLVM 演讲讲过析构插入；他认为新的地方是把这种扫描用在内存安全检查上。protestor（6 分）问，Polonius 的性能问题能不能靠改成反向实现缓解。</p>
<p>原文链接：https://verdagon.dev/blog/reverse-borrow-checking</p>
<h2>穷举搜索给 FPU 模拟器找到更短公式</h2>
<p>这是 purplesyringa 的文章，kibwen 在 2026 年 10 月 18 日把它发到 r/rust。采集时 60 分、3 条评论。文章日期是 2026 年 10 月 16 日。</p>
<p>文章要算的是：给定一个 f32，返回只保留最低置位的那个浮点数。例子写，二进制 <code>1.01101×2^10</code> 应返回 <code>2^5</code>。直接按位处理在 2 的幂上会出错，所以原先有一个 if：去掉尾数后仍等于自己就返回 x，否则用 <code>x - from_bits(bits &amp; (bits - 1))</code>。</p>
<p>作者用穷举搜索找不超过 5 次运算的公式。可选运算包括整数加减、按位 AND/OR/XOR，以及最后一步的浮点减法。5 个运算位、每个 6 种运算、42 种括号组合，一共 7776。输入可以是 x，或 64 个覆盖浮点字段的常数。搜索按运算次数归纳构造表达式，并用 <code>FxHashSet</code> 按输出值去重。作者写，去重之后整次搜索大约 4 分钟。测试用例后来加到 20 个，每条表达式存 80 字节。</p>
<p>搜索找到若干 5 运算公式。作者没有找到 4 运算公式。这个搜索把重复子表达式算成多次运算。手工检查后，最后一条 5 运算公式可以复用一次 <code>x.to_bits() &amp; !f32::MANTISSA_MASK</code>，写成 <code>let a = x.to_bits() &amp; !f32::MANTISSA_MASK; return f32::from_bits(x.to_bits() &amp; (a - x.to_bits())) - f32::from_bits(a);</code>。作者写，这个公式对 2 的幂会翻转符号位。代码在 https://github.com/purplesyringa/fpu-v/blob/d3c3f72c691698e5095d259a79610e5293911651/src/ops/multiplication.rs#L485 。仓库采集时 5 个 star，最近推送 2026 年 10 月 16 日。</p>
<p>评论里 dnew（16 分）写，几十年前有人用穷举最短指令序列实现 FORTRAN 的 ABS 和 SIGN。Zde-G（2 分）写，Intel 编译器里也有人对小整数乘法做过类似的事。</p>
<p>原文链接：https://purplesyringa.moe/blog/superoptimizing-an-fpu-emulator/</p>
<h2>职业用户给 Rust 求职的建议</h2>
<p>这是 scol2n 2026 年 10 月 18 日发在 r/rust 的提问，问用了大约 3 个月 Rust 之后，怎样开始用 Rust 工作。采集时 50 分、72 条评论。</p>
<p>tibbon 的评论有 249 分，写不要把职业绑在一种语言上，做能换工具的工程师。brainrotbro（24 分）写，很少看到只用 Rust 的职位，更常见的是同时要 C++ 和 Rust。solidiquis1（15 分）写，在航空航天、机器人和防务方向，南加州创业公司里的纯 Rust 职位在变多。bentNail28（4 分）建议先学 C++，理由是 C++ 有助于理解 Rust，而且需求更大，很多系统项目以 C++ 为主再接入 Rust。professionalnuisance（12 分）写，也有 Rust 加 Python（PyO3）的工作。juniperico（9 分）写，传统 Python 岗位里用 Rust 做优化的机会在变多。MishkaZ（1 分）写，自己在东京找到过一份 Rust 工作，之后再看到的 Rust 职位很少，而且常常和 crypto 或生成式 AI 有关。</p>
<p>原文链接：https://www.reddit.com/r/rust/comments/1x93thf/for_those_who_use_rust_professionally_what_advice/</p>
<h2>自写 SQL 字面量替换器</h2>
<p>这是 Lightforce_ 2026 年 10 月 18 日发在 r/rust 的说明，讲一个只替换 SQL 字面量、不建语法树的 tokenizer。采集时 0 分、3 条评论。帖子正文直接发在 Reddit，外部仓库链接已从正文里去掉。</p>
<p>作者写，目标是从生产 SaaS 的 trace 里看 N+1 和重复查询。该服务大约有 20 万客户。作者要查询结构，字面量不进入报告，因为数据在欧盟，适用 GDPR。<code>WHERE id = 42</code> 和 <code>WHERE id = 43</code> 要变成同一个模板。作者先试了正则，再看了 sqlparser。作者希望二进制小于 10 MB，只替换字面量。</p>
<p>tokenizer 读一条 SQL，返回把字面量换成 <code>?</code> 的模板，以及按出现顺序抽出的值。作者给的例子里，<code>status = 'active'</code> 和 <code>total &gt; 100</code> 变成两个 <code>?</code>，参数是 <code>["active", "100"]</code>。同一请求里五十条同模板、不同参数的查询可以看成 N+1。值只留在当次比较的内存里。模板可以进报告或看板。</p>
<p>实现是六状态状态机：<code>Normal</code>、<code>InString</code>、<code>InNumber</code>、<code>InDoubleQuote</code>、<code>InBacktick</code>、<code>InDollarQuote</code>。双引号和反引号标识符原样保留。美元引号覆盖 PostgreSQL 的 <code>$$</code> 和 <code>$tag$</code>。主循环按当前状态调用对应函数，对字节走一遍。作者写，它不识别列和 join，也不建语法树。</p>
<p>原文链接：https://www.reddit.com/r/rust/comments/1x988uz/why_i_wrote_a_dumb_sql_tokenizer_instead_of_using/</p>
<hr>
<p>From Rust中文社区 Mike</p>
<p>社区学习交流平台订阅：</p>
<ul>
<li><a href="https://rustcc.cn/" rel="noopener noreferrer">Rustcc论坛: 支持rss</a></li>
<li><a href="https://rustcc.cn/article?id=ed7c9379-d681-47cb-9532-0db97d883f62" rel="noopener noreferrer">微信公众号：Rust语言中文社区</a></li>
</ul>
]]></description><pubDate>2026-10-19 01:06:55</pubDate></item><item><title>量化交易系统工程师（Rust），机构 BDM， C++低延迟交易系统工程师，量化策略研究员（高频交易与做市），项目经理/项目总监（PMO），财务经理，斯巴达业务负责人，资深量化风险专家（交易与对冲），资深量化交易专家（对冲策略）。</title><link>https://rustcc.cn/article?id=db0c98b2-df3f-4fae-9cb1-27cbf2827a56</link><description><![CDATA[<p>Position 一：机构 BDM
Job Type: Full-Time ，Onsite-HK （提供 EP ）
PS：
1 、负责开发维护机构客户、交易公司和战略伙伴，推动区域及国际业务拓展，并协调客户接入、代表公司参会以支持长期增长。
2 、本科以上、2/8 年机构销售/业务拓展/合作管理经验，具备 Crypto 、衍生品及机构交易生态背景，中英文流利，有港新跨境市场、交易所/做市商/流动性资源者优先。</p>
<p>Position 二：C++低延迟交易系统工程师
Job Type: Full-Time ，Onsite-HK （提供 EP ）
PS：
1 、负责用现代 C++开发优化加密衍生品高频交易系统，覆盖行情、订单管理、执行、风控、仓位、监控及交易所 API 连接与故障排查。
2 、本科以上、2/7 年 C++低延迟或交易系统经验，熟悉 Linux 、多线程、网络编程和衍生品订单生命周期，有 HFT/做市/OMS/交易所 API 及 NUMA 、lock-free 、DPDK/RDMA 、Rust/Python/K8s 等经验优先。</p>
<p>Position 三：量化策略研究员（高频交易与做市）
Job Type: Full-Time ，Onsite-HK （提供 EP ）
PS：
1 、负责研究加密货币衍生品高频、做市和短周期策略，分析订单簿与订单流，构建考虑手续费、滑点、排队和延迟的回测仿真，并优化报价、库存、对冲与实盘验证。
2 、本科以上、2/7 年量化/算法交易/做市经验，具备 Crypto 衍生品研究、概率统计与 Python 回测能力，熟悉执行约束和偏差识别，有永续/期货做市、订单流建模、C++/ClickHouse 等经验优先。</p>
<p>Position 四：项目经理/项目总监（ PMO ）
Job Type: Full-Time ，Remote
PS：
1 、负责支持增长、市场及运营项目的执行推进、跨团队协作、交付跟进、风险升级，并推动项目管理流程标准化、模板/SOP 搭建和复盘优化。
2 、要求 2/10 年 PMO/项目管理/运营协调经验，有增长、市场或运营合作经验，必须项为二线交易所背景、市场活动或增长项目经验，能独立强势推动项目，不要执行岗。</p>
<p>Position 五：财务经理
Job Type: Full-Time ，Remote
PS：
1 、熟悉交易所资金全业务，负责多币种、多主体全盘账务、月结年结、报表差异分析，对接产研梳理财务需求并搭建优化对账核算系统，同时管理冷热钱包、银行账户、代币台账、链上对账和内控流程。
2 、要求财务/金融本科，3 年以上 Web3/加密交易所财务全盘经验，懂 Etherscan/Tronscan 链上对账，能独立对接产研提需求并出正确报表，Base 迪拜优先，有财务系统 0–1 经验，不要执行岗。</p>
<p>Position 六：斯巴达业务负责人
Job Type: Full-Time ，Remote
PS：
1 、作为核心业务线负责人，需传统金融背景、证券背景优先，熟悉基金产品运作，且最近 2 年必须深耕加密货币行业，精通跟单、带单、机器人交易产品运作规则。
2 、必须业务精通达到负责人级别，执行岗不看。</p>
<p>Position 七：资深量化风险专家（交易与对冲）
Job Type: Full-Time ，Remote
PS：
1 、建立覆盖场内交易、外部对冲和通道资金的风险分析体系，负责逐币种/账户/组合风险模型、限额阈值、压力测试、异常流量与逆向选择/markout 分析、对冲策略独立检验及事故归因，并用 Python/SQL 推动风控生产化。
2 、要求 5 年以上市场/量化风险或衍生品交易经验，熟练 Python/SQL ，深入理解永续期货、保证金、强平、资金费、基差、市场微观结构、VaR/ES 与压力测试，有主导风险框架和事件改进案例，纯合规/反洗钱/告警值守不匹配。</p>
<p>Position 八：资深量化交易专家（对冲策略）
Job Type: Full-Time ，Remote
PS：
1 、在批准的风险预算和资金约束内对对冲业务净收益负责，研究动态对冲比例、净额聚合、库存控制与再平衡，优化跨通道路由、Maker/Taker 、拆单与执行节奏，并主导 TCA 、损益归因和策略从研究到实盘的完整生命周期。
2 、要求 5 年以上量化交易/系统化做市/电子交易经验、至少 2 年实盘策略与 P&amp;L 管理，熟练 Python/SQL ，有主导研究进入实盘并持续运行的案例，必须具有独立交易经验，不要执行岗。</p>
<p>请携带简历咨询，谢谢。</p>
]]></description><pubDate>2026-10-18 09:53:10</pubDate></item><item><title>【Rust日报】2026-10-18 Vec 和 String 的枚举优化不只靠空指针</title><link>https://rustcc.cn/article?id=7f743182-8cb4-47ee-a474-87cee824dae5</link><description><![CDATA[<h2>Vec 和 String 的枚举优化不只靠空指针</h2>
<p>这是 kmdreko 2026 年 10 月 17 日发在 r/rust 的说明，讲 Vec 和 String 的枚举布局。采集时 129 分、24 条评论。</p>
<p>作者写，空指针 niche 可以让 <code>Option&lt;Vec&lt;_&gt;&gt;</code> 和 <code>Vec&lt;_&gt;</code> 占用同样的大小。作者原先以为，再增加几个变体就得单独放 discriminant。作者给出的例子含有一个 <code>String</code> 变体，以及 B、C、D、E 四个单元变体。作者在较新的编译器上测得 <code>size_of::&lt;String&gt;()</code> 和这个枚举都是 24。作者写，这个结果从 1.76.0 起可以观察到；作者查过 1.76.0 的发布说明，里面没有写到这一点。作者给出的最近公开说明是 https://stackoverflow.com/questions/79131922 。</p>
<p>Rust 1.99.1 的 alloc 源码把 capacity 定义成 <code>type Cap = core::num::niche_types::UsizeNoHighBit</code>，地址是 https://doc.rust-lang.org/1.99.1/src/alloc/raw_vec/mod.rs.html#39 。旁边的安全注释写，cap 必须小于等于 <code>isize::MAX</code>。评论里 _ChrisSD（61 分）写，相关关键词是 pattern types，标准库用 <code>UsizeNoHighBit</code> 这类包装类型，避免依赖还没稳定的语法，并给出 https://github.com/rust-lang/rust/blob/158f79d5c24d262f820fa45da96e7b77bc29a338/library/core/src/num/niche_types.rs#L116 。zdimension 写，该文件里的 pattern type 写法出现在宏参数中，宏会生成运行时检查。Sharlinator（42 分）写，希望以后有 <code>u63</code>、<code>u31</code> 这类类型；LLVM 支持任意位宽整数，pattern types 以后也可能稳定。</p>
<p>原文链接：https://www.reddit.com/r/rust/comments/1x8cj45/psa_enum_optimization_for_vecstring_can_use_the/</p>
<h2>通往 iroh 1.0</h2>
<p>这篇文章是 n0 团队的回顾，标题是 The road to iroh 1.0，记录 iroh 从 IPFS 实现走到稳定线格式的过程。kibwen 在 2026 年 10 月 17 日把它发到 r/rust，采集时 66 分、10 条评论。</p>
<p>iroh 是按公钥拨号的 QUIC 点对点连接库，仓库在 https://github.com/n0-computer/iroh ，仓库里有 Apache-2.0 和 MIT 两份许可证。采集时 GitHub 有 12,751 个 star。crates.io 当前版本是 1.3.0，发布于 2026 年 9 月 28 日；1.0.1 发布于 2026 年 6 月 29 日。总下载 3,367,195 次。文章写，1.0 表示线格式和 API 稳定，扩展点还在。</p>
<p>文章写，项目做了四年，代码没有使用 LLM。起点是 Rust 版 IPFS，目标是手机这类资源受限设备。blob 传输先做成 krakensync，内容寻址只用 BLAKE3。联网在两天内用 quinn 接上 QUIC。并行的 Delta Chat 聊天记录迁移需要可恢复的大文件传输，IPFS 兼容实现满足不了磁盘和依赖体积约束。团队因此停止兼容现有 IPFS 实现，旧代码留在 beetle。端点身份改成 Ed25519 公钥，传输只留 QUIC。</p>
<p>打洞方案参考 Tailscale，打不通时走 relay。地址查找后来用 pkarr 的格式，也可以直接走 BitTorrent mainline DHT。范围随后收窄成按端点 ID 直连，blob、gossip、docs 拆到独立 crate。0.35 作为长期稳定版，另开 canary 系列。为了让 QUIC 知道多条路径，团队 fork 了 quinn，实现叫 noq。站点写，iroh 已经在数十万台设备上跑生产。</p>
<p>原文链接：https://www.iroh.computer/blog/the-road-to-iroh-1-0</p>
<h2>Apalis 1.0.0 稳定</h2>
<p>Apalis 是 Rust 的后台任务和消息处理库，仓库在 https://github.com/apalis-dev/apalis ，许可证 MIT。作者 geoffmureithi 在 2026 年 10 月 17 日把 1.0.0 发到 r/rust，采集时 12 分、5 条评论。</p>
<p>crates.io 上 1.0.0 的发布时间是 2026 年 10 月 12 日，总下载 1,319,278 次。GitHub 采集时有 1,439 个 star。介绍博客的日期是 2026 年 10 月 16 日。发布说明在 https://github.com/apalis-dev/apalis/releases/tag/v1.0.0 。</p>
<p>1.0 把原来的单体 Backend trait 拆开。Backend 负责轮询、心跳和中间件。TaskSink 负责入队。Expose 负责队列、worker、任务过滤和指标。BackendFactory 负责多个 worker 共享连接。Worker 改成类似 Stream，需要被唤醒才消费任务。作者写，这样可以减少长轮询。</p>
<p>顺序工作流提供 and_then、filter_map、fold、repeat_until、delay_for、delay_with。DAG 工作流里没有依赖的节点并行执行，图在运行前做校验，可以打印成 DOT。1.0 还加上任务幂等、手动重试，以及 MonitorContext 和 TaskContext，可以从外部取消任务和 worker。新增的后端包括 RSMQ、NATS 和 PgMQ。已有后端包括 Redis、PostgreSQL、SQLite、MySQL 和内存。评论里 chicagoderp 写，自己的设计制造软件已经用 Apalis 跑了一年多。</p>
<p>原文链接：https://apalis.dev/blog/introducing-v1-2026-10-16</p>
<h2>哪些研究够得上 Rust 的下一代</h2>
<p>这是 Dyson8192 2026 年 10 月 17 日发在 r/rust 的提问，问哪些编程语言研究已经成熟到可以进入以后的 Rust，或进入遵循类似原则的后继语言。采集时 136 分、62 条评论。</p>
<p>帖子写，Rust 早期的一条原则是只采用已经经过验证的研究。作者在回复里写，这里的 2.0 指后继语言，不指按 SemVer 发布 Rust 2.0。</p>
<p>SirKastic23 的评论有 117 分，点名 linear types、algebraic effects 和 session types，并提到 Vale 设计者写过 linear types，以及 Rust 里讨论过的 must-move types。JoJoModding 的评论有 15 分，写 linear types 和并发、递归数据类型放在一起，还没有像 RustBelt 那样清楚的模型；leakpocalypse 说明，带 Rc 的 Rust 不能同时保证类型一定会被 drop。vlovich 的评论有 110 分，提到 Valen 的 linear types 和 group borrowing。Bassfaceapollo 的评论有 33 分，写自己在看 Hylo、Koka、Austral，并加上 Valen。seg_lol 贴了用 Rust 实现的语言 Par，仓库在 https://github.com/par-team/par-lang 。</p>
<p>原文链接：https://www.reddit.com/r/rust/comments/1x80208/research_that_has_matured_enough_for_rust_20/</p>
<hr>
<p>From Rust中文社区 Mike</p>
<p>社区学习交流平台订阅：</p>
<ul>
<li><a href="https://rustcc.cn/" rel="noopener noreferrer">Rustcc论坛: 支持rss</a></li>
<li><a href="https://rustcc.cn/article?id=ed7c9379-d681-47cb-9532-0db97d883f62" rel="noopener noreferrer">微信公众号：Rust语言中文社区</a></li>
</ul>
]]></description><pubDate>2026-10-18 01:07:36</pubDate></item><item><title>【rpi 进展】让 Rust Agent 更容易接入新模型：Provider 分层与插件扩展</title><link>https://rustcc.cn/article?id=67acd42f-ae7e-416c-8279-c81955673628</link><description><![CDATA[<p>给 Agent 接一个“兼容 OpenAI”的公司网关，协议代码可以复用，官方账号的 <code>OPENAI_API_KEY</code> 却不能因为协议兼容就自动拿来用。模型目录、服务端点和认证都属于这个网关自己的身份。</p>
<p>最近在 rpi 里推进 Provider 分层，就是想把这件事理顺：供应商怎么接入、凭据怎么绑定、增量怎么回来，由适配层处理；Agent 继续负责工具循环、会话和取消。接一个新服务，不应该顺手改一遍 Agent 的执行逻辑。</p>
<p>仓库：<a href="https://github.com/bigfish1913/pi-rust" rel="noopener noreferrer">https://github.com/bigfish1913/pi-rust</a></p>
<h2>先说 rpi 能拿来做什么</h2>
<p>rpi 是 Rust 原生的 coding-agent runtime，也提供基于这套运行时的终端编码助手。可以直接装 CLI 用，也可以把 <code>rpi-agent</code> 等 crate 嵌进自己的程序，自己掌控工具、事件和输出。</p>
<p>如果你已经有自己的工作流，还可以通过动态库扩展提供工具或 Provider。对 Rust 开发者来说，这条路径比较有意思：业务能力可以先在自己的嵌入式 Agent 里调试，再通过扩展适配器交给 rpi 宿主使用。</p>
<p>这次 Provider 工作服务的就是这个定位。核心依赖统一的 <code>Provider</code> 契约，内置实现和插件实现从同一入口被调用，上层消费统一事件。</p>
<h2>已有协议的新服务，尽量只加配置</h2>
<p>例如 OpenAI 官方和公司网关都使用 Chat Completions，它们可以复用请求编码和 SSE 解析代码，但要分别保留自己的 provider ID、模型目录、端点和凭据。</p>
<p>这带来两个直接好处：协议修复不用给每家供应商复制一遍；切到公司网关时，也不会仅因“兼容 OpenAI”就去读官方的 key。</p>
<p>当前代码已经支持通过 <code>models.json</code> 配置已有协议的新身份。更特殊的请求签名、私有接口等需求，可以沿 Provider 扩展方向接入。需要说明的是，插件的模型目录和认证声明还在收敛，暂时不能承诺任意新协议都能“装一个 package 就全部接好”。</p>
<h2>Rust 插件边界，选了 C ABI + JSON</h2>
<p>跨动态库直接传 Rust trait object、<code>String</code> 或异步运行时对象，会把宿主和插件绑在不稳定的 Rust ABI 上。rpi 的扩展边界使用 C ABI 函数指针和 JSON 信封，字符串由分配它的一侧释放。</p>
<p>这条路线允许插件不依赖宿主使用同一 Rust 编译器版本，但仍需遵守插件 ABI 和平台要求。代价也很实际：插件与宿主同进程，内存所有权、动态库持有和退出时机都得处理；它不是安全沙箱。</p>
<h2>插件也要边生成边显示，取消时及时返回</h2>
<p>开发分支里的流式 Provider 会通过回调交付 chunk，宿主把它们转成 Agent 和 TUI 消费的事件流。同步 FFI 调用放在 <code>spawn_blocking</code> 中，避免阻塞异步转发路径。</p>
<p>这里最关心的行为是：增量在结束前能被上层看到；一次请求只有一个终态；用户取消以 <code>Aborted</code> 结束，而不是再补一个成功完成。</p>
<h2>欢迎拿自己的接入需求来试</h2>
<p>如果你在用 Rust 做内部编码助手、给现有工具嵌 Agent，或者需要接公司的模型网关，可以从 rpi 的 CLI 或最小嵌入示例开始：</p>
<pre><code>cargo install rpi-cli
rpi --help
</code></pre>
<ul>
<li>项目与使用说明：<a href="https://github.com/bigfish1913/pi-rust" rel="noopener noreferrer">https://github.com/bigfish1913/pi-rust</a></li>
<li>官网：<a href="https://rpi.bigfisharc.cn/" rel="noopener noreferrer">https://rpi.bigfisharc.cn/</a></li>
<li>最小嵌入示例：<a href="https://github.com/bigfish1913/pi-rust/tree/162d0dd591504aa0a20d2693d8be774b2ad4d66b/examples/minimal" rel="noopener noreferrer">https://github.com/bigfish1913/pi-rust/tree/162d0dd591504aa0a20d2693d8be774b2ad4d66b/examples/minimal</a></li>
<li>插件示例：<a href="https://github.com/bigfish1913/pi-rust/tree/162d0dd591504aa0a20d2693d8be774b2ad4d66b/examples/plugin-stub" rel="noopener noreferrer">https://github.com/bigfish1913/pi-rust/tree/162d0dd591504aa0a20d2693d8be774b2ad4d66b/examples/plugin-stub</a></li>
</ul>
<p>这轮尤其想收集两类真实需求：现有 OpenAI/Anthropic 兼容网关在哪些地方并不兼容，以及私有认证、模型目录、取消语义中哪些部分需要扩展声明。欢迎带接口差异或最小复现提 issue；这些材料能直接帮助确定 Provider 与宿主的边界。</p>
]]></description><pubDate>2026-10-17 15:38:34</pubDate></item><item><title>RSTSR v0.10：Rust 原生、全面兼容 Python Array API 标准的科学计算高维张量库</title><link>https://rustcc.cn/article?id=9f9d32da-6d7c-4f94-9f8f-d8ade20ca417</link><description><![CDATA[<h1>RSTSR v0.10：Rust 原生、全面兼容 Python Array API 标准的张量库</h1>
<p>RSTSR 历时两年，现在到了阶段性的里程碑：CPU 下高效的、原生 Rust 的、<strong>与 NumPy 接口高度兼容</strong>的 n-维张量科学计算库。</p>
<p>我们认为，NumPy 在高维张量的接口设计是非常优秀的。我们在 RSTSR 中证明，Rust 语言原生科学计算可以做到 <strong>写起来、读起来像 NumPy，同时达到更高效、更安全、更适合并行计算</strong>。</p>
<ul>
<li>项目地址：https://github.com/RESTGroup/rstsr</li>
<li>API 文档：https://docs.rs/rstsr/latest/rstsr</li>
</ul>
<p>详见 RSTSR v0.10 相关博客：https://restgroup.github.io/rstsr-book/zh-hans/blog/rstsr-third-report</p>
<p>对于 NumPy 用户，RSTSR 提供了 <a href="https://docs.rs/rstsr/latest/rstsr/cheatsheet/index.html" rel="noopener noreferrer">NumPy-RSTSR Cheatsheet</a> 让你快速熟悉 RSTSR。</p>
<h2>全面兼容 Python Array API 2025 标准</h2>
<p>RSTSR 作为原生的 Rust 库，它实现了几乎所有 <a href="https://data-apis.org/array-api/latest" rel="noopener noreferrer">Python Array API</a> 2025 标准的接口。RSTSR 不再是“受 Array API 启发”，而是真正实现了 Array API 标准的非 Python 程序库。</p>
<p>Python Array API 2025 标准涵盖了几乎所有 NumPy 常用与重要的功能，包括：</p>
<ul>
<li>张量的创建：zeros, ones, full, arange, linspace, eye, meshgrid 等；</li>
<li>张量的索引：基础索引 (basic indexing/slicing)、高级索引 (advanced/fancy indexing)、元素索引 (element indexing)；</li>
<li>张量的形状操作：reshape, transpose, swapaxes, moveaxis, expand_dims, squeeze 等；</li>
<li>张量的广播操作：broadcast_to, broadcast_arrays 等；广播机制也应用于张量的算数运算等其他操作；</li>
<li>张量的算术运算：加减乘除、三角函数等；</li>
<li>逻辑运算、比较运算等二元操作；</li>
<li>张量的线性代数运算：matmul, vecdot, eigh, svd 等；</li>
<li>张量的统计运算：sum, mean, var, std, min, max 等；</li>
<li>张量的其他操作：concatenate, stack, split, repeat, tile 等。</li>
</ul>
<p>基于 RSTSR v0.10.0、Faer 后端的的简单 Python 封装程序 <a href="https://pypi.org/project/rstsr-faer-py" rel="noopener noreferrer">rstsr-faer-py</a> 可以在 PyPI 上下载；对 <a href="https://github.com/data-apis/array-api-tests" rel="noopener noreferrer">Array API 2025 测试套件</a> 结果是 1336 Pass / 17 Fail / 33 Skip (对比 NumPy 2.5 的结果是 1339 Pass / 42 Fail / 5 Skip)。其中，14 Fail / 33 Skip 是测试套件自身、以及 RSTSR Faer 后端未实现 FFT 功能；其余 3 Fail 是实际应用情景中罕见的 SVD 浮点数过大溢出问题。可以表明 RSTSR 除 FFT 功能外，正确实现了所有 Array API 2025 的接口。</p>
<p>尽管我们并非真的实现了所有 Array API 2025 的接口，但那是因为少量接口由于 Rust 语言本身的特性难以或不可能实现。因此我们即使在 Python 下存在解决方案，但原生 Rust 一一对应地实现。这些被排除的功能包括</p>
<ul>
<li>Python 中允许的 <code>__ipow__</code>, <code>__imatmul__</code>，但 Rust 不存在 (但可以用函数实现的) 的运算符重载；</li>
<li>Python 允许的动态类型列表，但 Rust 通过静态类型实现非常困难；受到影响的函数包括 <code>concat</code>, <code>stack</code> (但只要是相同类型的张量，RSTSR 仍然可以使用 <code>rt::concat</code> 和 <code>rt::stack</code>)。</li>
</ul>
<h2>RSTSR 的主要特性</h2>
<ul>
<li><strong>使用 <code>%</code> 作为矩阵乘法算符</strong>：这是 RSTSR 的一个特色。你可以使用 <code>&amp;a % &amp;b</code> 来执行 <code>a.matmul(&amp;b)</code>，这使得矩阵乘法的语法更加简洁。</li>
<li><strong>优秀的并行管理</strong>：针对多线程 BLAS 后端，我们通过 rayon 的线程控制，可以保证无论是否在 rayon 并行线程内部还是外部调用 RSTSR 的通用计算或矩阵线性代数，都能充分利用并行设备优势、且不会超出用户所指定的线程数。</li>
<li><strong>同时支持 row-major 与 column-major</strong>：RSTSR 默认支持 row-major 内存布局；但我们同时允许 column-major 内存布局，且在现实项目 REST 电子结构程序中已经大量使用。</li>
<li><strong>支持多种 BLAS 后端</strong>：RSTSR 可以使用 Faer 默认多线程后端，也可以使用 OpenBLAS、Intel MKL、BLIS、KML 等多种 BLAS 后端；在 CPU 下的性能表现与 NumPy 相当。支持如 solve, svd, eigh 等矩阵线性代数运算。</li>
<li><strong>可扩展后端</strong>：我们采用泛型以支持多后端。用户不需要修改 RSTSR 的源代码，不需要要求数据在内存 (GPU/硬盘/网络都可以承载数据)，只要实现新的后端 trait 接口，就可以使用自定义后端实现数学计算。</li>
<li><strong>支持多种数据类型</strong>：RSTSR 支持通常浮点数，也支持任意数据结构 (包括字符串等需要 alloc 的类型)；在电子结构程序中，f64 与 c64 是最常用的数据类型，我们对这些数据类型进行了支持和特殊优化。</li>
<li><strong>零开销 reshape 支持</strong>。在合理的张量布局下 (不一定必须是内存完全连续的)，RSTSR 可以使用视窗 (view) 的方式实现 reshape，而无需额外的内存开销。</li>
<li><strong>Einstein Summation 支持</strong>。在外接 TBLIS 张量缩并库的情况下，RSTSR 可以使用与 NumPy 相同的 Einstein Summation 语法进行张量缩并计算。详细见 <a href="https://docs.rs/rstsr/latest/rstsr/prelude/rstsr_funcs/tblis/fn.einsum.html" rel="noopener noreferrer"><code>rt::tblis::einsum</code></a>。</li>
<li><strong>高效的 Vecdot 支持</strong>。对于电子结构，特别是一部分稠密密度泛函矩阵计算，<code>"pi, pi -&gt; p"</code> 类型的张量缩并非常常见，且确实是不小的内存带宽耗时瓶颈。我们对 <a href="https://docs.rs/rstsr/latest/rstsr/prelude/rstsr_funcs/fn.vecdot.html" rel="noopener noreferrer"><code>rt::vecdot</code></a> 函数的实现并非是 naive 的；它在多核并行下性能优秀，比单纯的矩阵数乘后再求和要快许多，且内存开销更小。</li>
</ul>
<h2>RSTSR 在电子结构实际项目中的应用</h2>
<p>高维张量库 RSTSR 的设计初衷，是更好地解决电子结构计算中高维张量的存储与计算。RSTSR 基于 <a href="https://gitee.com/restgroup/rest" rel="noopener noreferrer">REST</a> (Rust-based Electronic Structure Toolkit) 电子结构程序平台开发。</p>
<p>RSTSR 的实战典型示例是，我们在 REST 电子结构程序中，实现了高效的杂化泛函二阶解析梯度 (REST <a href="https://gitee.com/restgroup/rest/pulls/154" rel="noopener noreferrer">PR !154</a>)。</p>
<p>Hessian 二阶解析梯度可以给出重要的化学性质，包括分子振动频率、热力学能；其衍生量可以给出红外光谱、拉曼光谱。它在谱学与热化学上有重要的应用价值，可以服务于药物设计、材料设计等上位学科任务。我们能表明 REST 程序在 RI-JK 近似下的 Skeleton 导数达到相当高的、达到甚至超过其他类似电子结构程序的性能，在 CP-HF 求解过程的 FLOPS 利用率到 40% 以上，同时在算法实现与程序优化上有出色的表现[^1]。而这些是基于 RSTSR 的高效张量计算实现的。</p>
<p>[^1]: Zhu, A. J.; Zhang, I. Y. Efficient Implementation of Hartree-Fock Hessian Skeleton Derivative with Resolution-of-Identity Approximation in REST. International Conference on Theoretical and High Performance Computational Chemistry (ICT-HPCC) 2026.</p>
]]></description><pubDate>2026-10-17 07:36:44</pubDate></item><item><title>【Rust日报】2026-10-17 zip crate 旧版本被 yank 后又恢复</title><link>https://rustcc.cn/article?id=7265d6a3-32e0-45de-833b-eeab0f27a17d</link><description><![CDATA[<h2>zip crate 旧版本被 yank 后又恢复</h2>
<p>zip 是 crates.io 上读写 zip 文件的库，仓库在 https://github.com/zip-rs/zip2 ，最新版本 9.0.4，总下载 303,621,963 次。2026 年 10 月 16 日，维护者 Pr0methean（Chris Hennick）从北京时间 11:32 起把一批 9.x 以外的版本 yank。martynp 在当天 13:47 打开 issue #1075，当时写除最新的 9.0.3 以外都已被 yank。维护者在 14:17 回复，列出的原因是 GHSA-vv5m-jxxh-4627、GHSA-4v9h-p7m9-rh26、GHSA-4684-h2q9-2vcp，以及本月稍后才会公开的其他安全问题。</p>
<p>9.0.0 发布于 10 月 9 日，9.0.4 发布于 10 月 16 日 17:09。维护者在 23:48 写，9.0.0 到 9.0.4 都是在已知安全问题还在的情况下发出的，用来先发布已经合并的修复。同一天 21:44，维护者写 crates.io 显示超过 90% 的下载仍来自有已知问题的版本，现行安全策略是在公开这些问题之前先 yank 相关版本。</p>
<p>10 月 17 日 00:51，维护者恢复了 8.6.0、7.4.0、6.0.0、5.1.1、4.6.1 和 3.0.0，并写明这些版本会保持可解析到 10 月 30 日，或到对应大版本的 backport 发布，以先到者为准。crates.io 的审计记录显示，到 10 月 17 日 08:22，8.5.1、7.2.0、0.6.6 等更多版本也被 unyank。采集时 136 个版本里有 17 个仍是 yanked。这次操作后仍保持 yanked 的是 0.10.0-alpha.1，以及一批 0.1 和 0.0 版本。2.0.0 的 yank 记录在 2025 年 3 月 17 日。</p>
<p>DelusionalPianist 把这件事发到 r/rust，采集时 59 分、83 条评论。一条评论写 crates.io 上 zip 有 3983 个反向依赖。另一条评论说明，yank 不会删除已发布的 crate；锁文件里已经记下的版本仍可解析，cargo add 和 cargo update 不会再选中被 yank 的版本。</p>
<p>原文链接：https://github.com/zip-rs/zip2/issues/1075</p>
<h2>多系统模拟器 Sly 公开</h2>
<p>Sly 是作者 ioncodes 用 Rust 写的多系统模拟器，仓库在 https://github.com/ioncodes/sly ，许可证 GPL-3.0，网站是 https://sly.layle.dev/ 。作者在 2026 年 10 月 16 日把它发到 r/rust，采集时 173 分、25 条评论。作者也在做 GameCube 和 Wii 模拟器 Gecko，帖子里写不会因此放下 Gecko。</p>
<p>首发支持 Game Boy Advance 和 SNES。作者写 SNES 支持很好；多数 GBA 游戏能运行，还没有音频，游戏存档还不支持，即时存档可用。计划中的系统包括 PS1、Game Boy、Game Boy Color、Sega Genesis、Dreamcast、GameCube 和 Wii。核心由作者自己编写，不封装 libretro。</p>
<p>桌面端有三个前端。Sly Launcher 把游戏库显示成 3D 盒子和卡带，可以自动下载封面，支持地区包装和单游戏覆盖。Sly Classic 是 Qt 界面，用 C++ 编写，带游戏列表、1 到 4 倍缩放，以及 1 个快速存档位和 10 个编号存档位。Sly Debugger 用 GPUI，可以单步执行指令和事件，查看线性和图形反汇编、CPU 寄存器、调用栈、内存、MMIO、DMA、贴图、tilemap、背景、精灵和调色板，并为 SA-1、Super FX 提供单独工作区，还带内置 Lua 编辑器。iOS 应用用 Swift。Classic 和 iOS 调用 Rust 核心。</p>
<p>Windows、macOS 和 Linux 各有 Launcher、Classic、Debugger 的独立压缩包。调试器可以在支持 WebGPU 的浏览器里打开，地址是 https://sly.layle.dev/app 。iOS 提供未签名 IPA，需要侧载。Android 还在开发。GitHub 仓库采集时有 85 个 star。</p>
<p>原文链接：https://github.com/ioncodes/sly</p>
<h2>Yapfast：闲置约 40MB 的 Discord 客户端</h2>
<p>Yapfast 是用 Rust 和 Slint 写的 Discord 客户端，网站是 https://yapfast.com ，仓库在 https://github.com/yapfast/yapfast ，许可证 GPL-3.0。站点写版本 0.1.0 是 beta，发布日是 2026 年 10 月 16 日。JameEnder 发到 r/rust，采集时 28 分、60 条评论。</p>
<p>站点给出的对比是：同一账号登录后闲置，Yapfast 约 40MB，Discord 桌面版约 800MB；从图标到可用窗口，Yapfast 0.22 秒，Discord 桌面版 8 秒。测量日期是 2026 年 10 月 15 日，两台机器，启动时间取第二次启动。测量方法写在 https://github.com/yapfast/yapfast/blob/main/docs/measurements/README.md 。作者在帖子里写，Slint 使用 Skia 软件渲染，内存大约是 GPU 渲染的一半；房间列表在核心里只保留一份；时间线只重建发生变化的行；正在观看的流直接写进 UI 显示的帧。语音降噪用的是 DeepFilterNet。</p>
<p>站点写 Windows 10 和 11 可以下载，Linux 需要自行构建，还没有 macOS 构建，也没有 Linux 安装包。登录方式是用 Discord 手机应用扫描二维码。站点写 Yapfast 看不到密码，登录 token 放在系统凭据存储里，只发给 Discord。没有中间服务器，消息从本机直接发到 Discord，或发到用户自己的 Matrix 服务器。Matrix 仍支持加密房间、Spaces 和 MatrixRTC 语音；Windows 发行版目前只有 Discord，要同时使用两边需要从源码构建。</p>
<p>站点列出的已有功能包括服务器、频道、私信、群私信、回复、编辑、反应、置顶、附件、Markdown、embed、自定义表情、贴纸和剧透，以及频道旁的帖子串、带 Discord 过滤器的服务器搜索、语音频道、私信通话、单人音量、Go Live、观看直播和摄像头。尚未完成的包括论坛频道、按键说话、soundboard、投票、活动、服务器设置、服务器文件夹、通过邀请加入、按 Discord 的方式转发，以及消息里的动画自定义表情只显示第一帧。第三方客户端违反 Discord 服务条款。站点写不能保证账号不会被封，并写实际被封的账号多与垃圾信息或自动化有关。</p>
<p>原文链接：https://yapfast.com</p>
<h2>Niko Matsakis 谈 agent 与 Rust</h2>
<p>这篇文章是 Niko Matsakis 2026 年 10 月 14 日发在 baby steps 上的博文，配套他本周在 SPLASH 的 REBASE 上的演讲。typesanitizer 在 10 月 16 日把它发到 r/rust，采集时 21 分、29 条评论。</p>
<p>文章引用 David Tolnay 的一段话：今年到目前为止，Meta 工程师写出的第一方 Rust 代码量，是过去 9 年总和的两倍；同一张图里 TypeScript 的同比增长被裁到图外，数字是 +1200%。文章把软件生产分成设计、构建、优化三块。优化部分提到 profiler dial9，仓库在 https://github.com/dial9-rs/dial9 ，用来查看 async 里的 long poll 和阻塞。</p>
<p>可靠性部分写，要把“能编译就大致能工作”再往前推。文章列出类型系统还盖不住的例子，包括某个方法只读一个字段、内部引用，以及不记录个人身份信息。作者希望把证明工具接进可扩展的编译器，少用宏和钉死的编译器版本。文中的北极星是证明写出的 unsafe 代码正确，并且不会造成未定义行为。作者在同一段写明，unsafe 关键字仍会使用。</p>
<p>设计部分写，当前常见做法是先写 markdown 文档，再指望 agent 照着做。作者提到可以把接口和实现分开，方便单独审查接口，也方便看到 agent 改了接口。结论里写，默认性能加上类型系统护栏，是 Rust 适合 agent 写代码的两点；权重可以往人更专注读代码、agent 更专注写代码调整。</p>
<p>原文链接：https://smallcultfollowing.com/babysteps/blog/2026/10/14/agentic-dev-and-rust/</p>
<hr>
<p>From Rust中文社区 Mike</p>
<p>社区学习交流平台订阅：</p>
<ul>
<li><a href="https://rustcc.cn/" rel="noopener noreferrer">Rustcc论坛: 支持rss</a></li>
<li><a href="https://rustcc.cn/article?id=ed7c9379-d681-47cb-9532-0db97d883f62" rel="noopener noreferrer">微信公众号：Rust语言中文社区</a></li>
</ul>
]]></description><pubDate>2026-10-17 01:08:23</pubDate></item><item><title>【Rust日报】2026-10-16 rustc 分不清不同文件路径</title><link>https://rustcc.cn/article?id=c237605d-ddf3-4d83-8676-1174cdd05ce9</link><description><![CDATA[<h2>rustc 分不清不同文件路径</h2>
<p>#164348 是 rustc 的一份误编译报告，标题是 miscompilation via engineered StableSourceFileId hash collisions。jsnell 在 2026 年 10 月 15 日提交，目前仍开放，GitHub 上有 15 条评论。标签包括 P-high、C-bug、T-compiler、A-filesystem、I-miscompile 和 regression-from-stable-to-stable。noop_noob 把它发到 r/rust，目前 486 分、83 条评论。报告在 1.99.0 和 nightly-2026-10-11 上复现。</p>
<p>rustc 用路径哈希区分源文件。Path 的哈希会忽略分隔符。PR #127297 把路径组件的长度混进哈希之后，issue 写明碰撞仍然容易出现。哈希相撞时，编译第二个文件会换成第一个文件的内容。Reddit 帖子举的例子是 <code>data/baselines/table.rs</code> 和 <code>database/line/stable.rs</code>。发帖人补充，去掉斜杠后文本相同还不够，还要再撞上哈希才会触发。</p>
<p>issue 写明，审查如果分别看两个路径，不会看到内容已经被替换，因为多数审计工具不会按同样的方式计算路径哈希。建议的修复是用整条路径的密码学哈希作为 source file id，不做归一化。碰撞会影响结果的地方，不再使用 Path 的哈希。相关说明见 https://github.com/rust-lang/rust/issues/127254#issuecomment-2205452710 。</p>
<p>原文链接：https://github.com/rust-lang/rust/issues/164348</p>
<h2>Rust 1.99.1 修复三处回归</h2>
<p>Rust 1.99.1 是 Rust 团队在 2026 年 10 月 15 日发布的补丁版本。公告写明它修的是此前版本引入的回归。noop_noob 发到 r/rust，目前 151 分、11 条评论。</p>
<p>缺少 wcslen 符号的问题记在 #163614。部分目标链接时找不到 wcslen，compiler-builtins 现在提供了回退实现。LLVM 的 loop-idiom-wcslen pass 可能插入对 wcslen 的调用，有些目标的 libc 里没有这个函数。UEFI 目标上，用了 std 的项目会坏，因为预编译标准库里已经带上这类调用。同样的用户代码模式也可以复现。</p>
<p>x86_64 上 FFI 返回 bool 的误编译记在 #163911。通过 FFI 返回 bool 的函数可能让返回寄存器的第 1 到第 7 位保持未指定，调用方会读到 0 和 1 以外的值。这个返回类型重新标成零扩展，以符合 ABI。</p>
<p>macOS 上 rust-lld 加载不了 libLLVM 的问题记在 #163947。不经过 rustup 代理直接调用编译器时，链接器可能找不到库搜索路径。现在 rust-lld 构建时带上了 libLLVM.dylib 所在目录的 rpath。</p>
<p>一条评论统计，1.96.1、1.97.1、1.98.1 和 1.99.1 是连续四个因误编译发出的补丁版本，并写明上一次同类修复在 1.80.1。</p>
<p>原文链接：https://blog.rust-lang.org/2026/10/15/Rust-1.99.1/</p>
<h2>TRACTOR 公布首份 C 到 Rust 翻译评测</h2>
<p>这份报告是 MIT 林肯实验室给 DARPA TRACTOR 项目做的第一轮测试评估，日期是 2026 年 2 月 20 日，共 76 页。作者包括 Hamed Okhravi、Noah Luther、Ian McQuoid、Brandt Ogden、Howard Mak、Nicholas Strega 和 Nathan Burow。Rodrigodd_ 在 2026 年 10 月 15 日把它发到 r/rust，目前 5 分。项目页在 https://www.ll.mit.edu/r-d/projects/translating-all-c-rust-tractor-benchmarks 。</p>
<p>TRACTOR 要做的是把大型 C 代码库翻译成 Rust，同时保持功能，并比较安全性、性能和代码质量。评测方是 MIT 林肯实验室。六个团队按主承担单位简称是 Aarno Labs、Galois、Intel、华盛顿大学、威斯康星大学和耶鲁大学。报告要求 LLM 接入可以替换，不能绑死某一家模型。</p>
<p>第一套测试 Battery 01 有 150 个用例。范围限定在明确的指针用法、简单数据结构、常规错误处理和静态程序结构，避开动态分配和复杂别名。功能正确率：耶鲁大学 98.7%（148/150），Aarno Labs 95.3%（143/150），Galois 90.7%（136/150），Intel 90.0%（135/150），威斯康星大学 80.7%（121/150），华盛顿大学 48.0%（72/150）。各队平均失败率 17.8%。</p>
<p>安全性按每个测试的 unsafe 操作数计，Intel 是 1.56，Aarno Labs 是 13.69。运行时开销中位数，威斯康星大学是 4%，Aarno Labs 是 5%。地道程度按可读性、语法、类型三项打分，满分 3。Intel 是 2.67、2.89、2.67，Aarno Labs 是 1.90、1.50、1.10。</p>
<p>六条路线可以分开看。Aarno 的 Tenjin 以确定性转译为主，走 C2Rust，自动模式不靠 LLM 合成。Galois 的 CRISP 把确定性转译和有界的 LLM 安全改写放在一起。Intel 的 IDEAS 按依赖顺序做片段级 LLM 翻译，并限制不生成 unsafe。华盛顿大学用工具编排的项目级 LLM 翻译。威斯康星大学用整项目 LLM 流程，靠构建失败迭代修复。耶鲁的 PROCTOR 在转译之后用静态分析做 Rust 到 Rust 的细化，减少 unsafe。</p>
<p>原文链接：https://github.com/DARPA-TRACTOR-Program/Reports/blob/main/First_TRACTOR_Evaluation_Report.pdf</p>
<h2>Miro 的 PDF 阅读器维护满一年</h2>
<p>Miro 是作者 Vincent Uden 用 Rust 写的 PDF 阅读器，仓库在 https://github.com/vincent-uden/miro ，crates.io 上的名字是 miro-pdf。这篇博客写的是项目发布一年后的维护情况。xorvralin2 发到 r/rust，目前 24 分。阅读器依赖 AGPL-3.0 的 mupdf，Rust 绑定是 mupdf-rs。</p>
<p>仓库里来自其他人的 issue，到 2026 年 9 月 26 日有 52 个，45 个已关闭，7 个仍开放。作者按主问题分成互斥类别。输入、导航和视图控制 15 个，构建、安装和发布 9 个，渲染、布局和文本 8 个，崩溃、卡死和资源占用 7 个。上游 mupdf-rs 已经合并 3 个相关贡献，另有 1 个已合并、还没发版。Wez Furlong 在 #53 里给过键位建议。</p>
<p>作者记录过一次泄漏：HashMap 的 key 构造不正确，渲染缓冲没有被丢掉。下一个版本 0.13 计划加上批注，包括下划线、删除线、高亮、手绘、评论和回复，以及裁剪、缩放和删除页面。作者也在考虑改名，因为 miro 和别的产品重名，crates.io 上已经用了 miro-pdf。</p>
<p>原文链接：https://www.uden.dev/blog/i-still-hate-acrobat</p>
<hr>
<p>From Rust中文社区 Mike</p>
<p>社区学习交流平台订阅：</p>
<ul>
<li><a href="https://rustcc.cn/" rel="noopener noreferrer">Rustcc论坛: 支持rss</a></li>
<li><a href="https://rustcc.cn/article?id=ed7c9379-d681-47cb-9532-0db97d883f62" rel="noopener noreferrer">微信公众号：Rust语言中文社区</a></li>
</ul>
]]></description><pubDate>2026-10-16 01:07:38</pubDate></item><item><title>从 44 万个&quot;幽灵&quot;说起：基于Rust开发的OntoDB 把关系、图、向量、本体等多模态数据融进一个内核，与一次 HNSW 召回坍塌的完整排查</title><link>https://rustcc.cn/article?id=ef3cc6b3-a566-4528-829d-c034aae0c481</link><description><![CDATA[<h2>一、先把结论放前面</h2>
<p>一个 227 万条化合物指纹的 HNSW 索引，召回率不对。不是低，是<strong>低得反常</strong>：</p>
<p><code>Recall@10  ≈ 0.88</code><br>
<code>Recall@50  ≈ 0.85     ← k 越大，找回来的反而越少</code></p>
<p>在健康的 HNSW 上，固定 <code>efSearch</code> 时 <code>Recall@k</code> 应随 k 增大走平甚至逼近 1。倒挂意味着"排在前面的找得到，第 10 到第 50 名够不着"——候选集本身不完整，不是排序问题。</p>
<p>最终查出来的是一串叠加的缺陷：一行严格小于号、两个没进快照的内存状态、一条四段式的数据失败链。修复后 <code>id-recall@10</code> 从 0.844 回到 <strong>0.9784</strong>，<code>dist-recall@10</code> <strong>0.9964</strong>，倒挂从 0.044 收敛到 0.004，图节点数与 SQL 侧精确对齐到 <strong>1,638,397</strong>。</p>
<p>这篇文章的主体就是这次排查。开始之前，先用一小节交代清楚"我们在什么东西上踩到了这个坑"。</p>
<hr>
<h2>二、OntoDB 是什么：一个内核装进 12 种数据模型</h2>
<h3>2.1 拼出来的多模，问题不在性能，在一致性</h3>
<p>主流的多模方案本质是"多套存储 + 应用层编排"：关系在 Postgres、图在 Neo4j、向量在 Milvus、时序在 InfluxDB、本体推理在 Jena，靠 ETL 和中间件对齐。</p>
<p>它的痛点很少出现在单点性能上，而出现在<strong>缝上</strong>：</p>
<ul>
<li>跨系统的写入无法组成一个事务，向量索引与关系数据之间必然存在一个"不一致窗口"，而窗口里的查询结果<strong>是错的、且看不出来</strong>；</li>
<li>同一个业务实体被拆到四五个系统，各存一份，靠 <code>id</code> 映射表勉强对齐；</li>
<li>一次查询要串联多家系统，延迟是各家之和，可解释性在拼接处断掉；</li>
<li>数据冷热度、安全策略、审计规则要在每一套系统上各配一遍。</li>
</ul>
<p>我们的选择是<strong>不拼</strong>：把这 12 种数据模型做进一个 LSM 存储引擎、一套事务体系、和一个查询语言里。下面就是它实际的样子。</p>
<h3>2.2 一个 LSM 引擎，12 种数据类型</h3>
<p>核心的存储是一套 LSM-Tree，通过<strong>键前缀路由</strong>区分数据形态：不同前缀走不同的编解码、索引结构和查询算子，但共用同一份 WAL、同一套 compaction、同一块 block cache。前缀划分覆盖 12 种数据类型：</p>
<table>
<thead>
<tr>
<th>类别</th>
<th>数据类型</th>
<th>关键结构</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>基础</strong></td>
<td>键值、文档（JSON/BSON）、全文（倒排+BM25+中英文分词）、多媒体元数据（SHA256 内容哈希）</td>
<td>LSM 键值、倒排索引、内容哈希索引</td>
</tr>
<tr>
<td><strong>高级</strong></td>
<td><strong>关系</strong>（结构化记录+事务）、<strong>图</strong>（属性图+遍历）、<strong>向量</strong>（HNSW 语义相似）、<strong>三元组</strong>（SPO 知识图谱）</td>
<td>见下文详解</td>
</tr>
<tr>
<td><strong>时序空间</strong></td>
<td>时序（TSM 列式 Delta/Gorilla 编码）、空间（R-Tree+GeoHash）、时空联合索引</td>
<td>TSM 列式块、四叉树</td>
</tr>
<tr>
<td><strong>实时</strong></td>
<td>流数据（CDC 变更捕获+连续查询）、事件（复杂事件处理 CEP）</td>
<td>WAL 直出 CDC、事件窗口匹配</td>
</tr>
</tbody>
</table>
<p>其中四种模型是这次踩坑的主角，也是 AI 场景里最常同时出现的四件套——它们的前缀命名空间和核心数据结构如下：</p>
<table>
<thead>
<tr>
<th>模型</th>
<th>存储形态</th>
<th>核心数据结构</th>
<th>键前缀</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>关系</strong></td>
<td>结构化记录</td>
<td>LSM-Tree；<strong>二进制行零拷贝谓词过滤</strong>（在二进制数据上直接做过滤，无需反序列化，解析时间减少约 60%）</td>
<td>普通表键</td>
</tr>
<tr>
<td><strong>图</strong></td>
<td>属性图（顶点 + 边 + 属性）</td>
<td>index-free adjacency，<code>Vec&lt;Vec&lt;(u32, String)&gt;&gt;</code> 内存邻接</td>
<td><code>__graph_v__</code> / <code>__graph_e__</code></td>
</tr>
<tr>
<td><strong>向量</strong></td>
<td>HNSW 索引 + 向量载荷</td>
<td>内存 HNSW 图 + 快照持久化 + 增量补录</td>
<td>向量索引命名空间</td>
</tr>
<tr>
<td><strong>本体</strong></td>
<td>SPO 三元组</td>
<td>内核内 OWL 2 RL 推理引擎，含 <code>inferred_from</code> 溯源</td>
<td><code>__triple__</code></td>
</tr>
</tbody>
</table>
<p>这四者共享同一套 WAL、同一套 compaction、同一套事务边界——<strong>不是"一个进程里装了四个库"，而是"一份数据上开了四种视图"</strong>。</p>
<p>图引擎值得一提：字符串 ID 只映射一次，之后全链路走 u32 整数索引，取邻居就是数组下标访问，不做哈希、不比字符串：</p>
<p><code>id_to_idx: RwLock&lt;HashMap&lt;String, u32&gt;&gt;,   // 只在这里做一次字符串映射</code><br>
<code>idx_to_id: RwLock&lt;Vec&lt;String&gt;&gt;,</code><br>
<code>adj_out:   RwLock&lt;Vec&lt;Vec&lt;(u32, String)&gt;&gt;&gt;,  // 出邻居</code><br>
<code>adj_in:    RwLock&lt;Vec&lt;Vec&lt;(u32, String)&gt;&gt;&gt;,  // 入邻居</code></p>
<p>k-hop 遍历的复杂度只与访问到的节点数相关，与图规模无关。遍历本身是 FIFO 队列 + 位图 <code>visited</code>，循环体内全是 u32 运算。企业版进一步换成 CSR 压缩存储（内存约省 50%），并用 Rayon 做并行邻居扩展。</p>
<p>本体层则是把 <strong>OWL 2 RL 推理引擎嵌进了存储内核</strong>：子类传播、等价类、传递性、对称性、逆属性、子属性等规则在写入时即触发（增量不动点约 50µs/事实），推导结果与原始事实在同一个事务边界内持久化，并记录来源规则与输入事实——<code>inferred_from</code> 让"这条结论从哪几条事实推出来的"可以被追问到具体的写入和规则触发点。对一个要给 Agent 用的数据库来说，<strong>可溯源不是加分项，是及格线</strong>。</p>
<h3>2.3 把十二种模型缝在一起的两根线</h3>
<p><strong>第一根：统一实体锚点。</strong> 一个字符串同时充当全部模型的键：</p>
<p><code>EntityId = {namespace}::{class}::{pk}</code></p>
<p>于是"化合物 A 的关系行""化合物 A 的图顶点""化合物 A 的向量文档""化合物 A 的时序记录"指向的是同一个实体——零映射表、零 ETL、没有"对不齐"的可能。前缀里的 <code>{namespace}</code> 不是装饰，是<strong>内核级多租户隔离</strong>：本体定义、数据、索引、推理都在命名空间范围内生效，键前缀路由零开销，不会出现"应用层加 tenant_id 容易漏过滤"的问题。</p>
<p><strong>第二根：同一套事务。</strong> 一次写入同时触碰多类结构，走的是同一套提交协议（三阶段锁：准备 → 预提交 → 提交，用来避免写锁与索引锁嵌套死锁）。这也是为什么后来那个"幽灵"问题只能靠<strong>一致性对账</strong>来解决——因为在我们的架构里，图、向量、关系本来就是同一份数据的不同视图，视图之间不对齐，是一种"内部矛盾"，而不是"外部同步延迟"。</p>
<p>数据完整性的最后一道防线在块级：SSTable 每页带 CRC，读路径做哨兵校验，损坏数据被<strong>确定性拒绝</strong>而不是悄悄吐错值；配合 Raft 副本（企业版）可以自动从健康副本修复。这不是"防御性编程"的口号——后面的排查里会看到，我们自己就被一个"读旧版本"的数据层 bug 咬过。</p>
<h3>2.4 一次写入，十二种模型同时就绪；活数据会自己冷</h3>
<p>写入侧是原子联动：文档写入 → 图顶点/边 → 三元组 → 推理 → 向量 → 全文/时序/空间索引全部在同一事务内落盘。数据落地的那一刻，它同时是"可被图遍历的""可被向量检索的""可被本体推理的""可被全文检索的"。没有异步索引队列，也就没有"刚写完查不到"的中间态。</p>
<p>除了"写完即就绪"，每条数据从落地开始就在按<strong>活数据（Live Data）机制</strong>运行：</p>
<ul>
<li><strong>三级半衰期</strong>：高频热点 7 小时 → 中频温数据 70 天 → 低频冷数据 2 年</li>
<li><strong>三种衰减模型</strong>：指数（默认）、线性、对数</li>
<li><strong>访问自动激活</strong>：每次查询命中自动重置衰减时钟，累加价值得分</li>
<li><strong>向量索引联动</strong>：高价值数据的向量优先加载到内存，冷数据向磁盘下沉</li>
</ul>
<p>传统 TTL 是"到点就死"，不理解数据对用户的真实价值；活数据机制让数据"越用越活、不用自动降权"。对 Agent 的长期记忆来说，这比单纯的持久化更重要——记忆不是永恒的，但不该被一刀切清理。</p>
<h3>2.5 查询语言也统一了：OntoQL</h3>
<p>不是"一个进程里装四套查询解析器"，而是<strong>单一查询语言 OntoQL</strong>融合关系投影/过滤/聚合、属性图遍历、向量近邻、时序窗口、空间谓词与本体推理；同时标准 SPARQL 1.1 查询（FILTER/OPTIONAL/UNION/EXISTS）也可直接使用。查询优化器会根据模态组合自动选择执行计划，比如"先用关系过滤缩小范围，再走向量近邻，最后在命中集上做图遍历"这类混合查询由优化器下推到存储层完成，不需要应用层拼装。</p>
<p>对"变化"的处理也是一等公民：<code>SUBSCRIBE</code> 原语支持订阅"某靶点家族新增相似分子""某子图边变化""某设备时序异常"这类条件，数据库主动推送，不需要外挂 Kafka 或应用层轮询；内核级 CDC 直接从 WAL 提取变更事件，Flink/Spark 可消费。</p>
<p>协议接入同样是多模的：PostgreSQL（5432）、MySQL（3306）、HTTP REST（7912）三套协议由内核直接解析——不是代理转发，而是协议级实现。现有应用不加中间层就能接入，原有 ORM、BI 工具可以继续用。</p>
<h3>2.6 为什么是 Rust</h3>
<ol>
<li><strong>无 GC → 确定性延迟。</strong> 向量检索是长尾敏感的，p50 看不出问题而 p99 会跳一个数量级；没有运行时 GC，"驻留内存"这件事不至于在某次搜索中间突然变成一次停顿。</li>
<li><strong>所有权模型 → 锁外计算、锁内交换。</strong> 491MB 的 HNSW 快照加载，我们早期把反序列化干在了写锁里，结果是几秒钟内所有并发搜索全部阻塞。修复后的结构是"锁外完成全部反序列化与校验，锁内只做一次指针交换"——而让这个结构成为<strong>纪律</strong>而不是<strong>自觉</strong>的，是借用检查器：你没法在持有 <code>&amp;mut</code> 的同时把数据再借出去算别的东西，临界区的边界在类型系统里就是可见的。</li>
<li><strong>单二进制、零运行时 → 部署形态覆盖边缘。</strong> 客户拿到的是一个可执行文件，<code>--data-dir</code> 指过去就能起；从边缘服务器到云，跑的是同一份内核代码，不依赖 JVM/Python 运行时。</li>
</ol>
<p>好，背景交代完了。下面进入正题。</p>
<hr>
<h2>三、一次 HNSW 召回坍塌的完整排查</h2>
<h3>3.1 现象：Recall@50 低于 Recall@10</h3>
<p>数据规模：227 万条 Morgan 指纹（1024 位二进制，Tanimoto 距离）。现象就是开头那两行——<code>Recall@10 ≈ 0.88</code>，<code>Recall@50 ≈ 0.85</code>。</p>
<h3>3.2 三次排除，排除掉三个错误假设</h3>
<p>我们没急着调参，先做排除。而且用的是<strong>分层大样本</strong>（500 节点，按 fp popcount 五分位抽样），不是拍 25 个点就下结论：</p>
<ol>
<li><strong>自检索 sanity check</strong>：用图中已存在的节点当查询，看它能否找回自己。结果 <strong>self-recall = 1.00</strong>（5000 样本下 0.9972）——图是连通且可导航的，<strong>排除"图结构崩坏"</strong>。</li>
<li><strong>距离口径对照</strong>：Tanimoto 是离散距离，可能有大量并列。id 口径与 dist 口径各测一遍，两者只差约 0.018（几乎全是并列距离造成的）——<strong>排除"并列造成假象"</strong>。</li>
<li><code>efSearch</code> <strong>扫描</strong>：从 64 提到 800，召回只从 0.72 涨到 0.89 就见顶——<strong>排除"搜索深度不够"</strong>。</li>
</ol>
<p>三次排除之后，剩下的可能性只有一个：<strong>真邻居压根不在可达子图上</strong>。边被系统性剪坏了，搜索再深也进不去。</p>
<h3>3.3 根因一：一行严格小于号</h3>
<p>问题出在 HNSW 的多样性剪枝启发式里：</p>
<p><code>// 对候选邻居 c，检查已被选中的邻居 r 是否"覆盖"了 c</code><br>
<code>// 若 r 到 c 比 q（新插入节点）到 c 更近，说明 c 由 r 代表即可 → c 冗余、可剪</code><br>
<code>for r in &amp;selected {</code><br>
<code>    if dist(r, c) &lt; dist(q, c) {   // ← 问题在这一行的边界语义</code><br>
<code>        drop(c);</code><br>
<code>    }</code><br>
<code>}</code></p>
<p>在连续欧氏空间里，两个距离完全相等的概率是 0，这行怎么写都不出问题。但 <strong>Morgan 指纹是 1024 位二进制，Tanimoto 是离散值——并列是常态，不是例外</strong>。于是大量数值上并不冗余的新节点，被系统性判为"冗余"剔除。</p>
<p>更隐蔽的是<strong>触发条件</strong>：</p>
<ul>
<li>建图初期邻居列表远没到上限，<strong>剪枝根本不会被触发</strong>——所以早期写入的 146 万向量质量是好的；</li>
<li>图饱和之后，<strong>每次增量插入都会触发剪枝</strong>——后续写入的向量入边被反复切断，逐渐沦为孤点。</li>
</ul>
<p>这解释了全部观测：早期批次正常、后期批次下滑、@50 倒挂、部分区域"几乎什么都搜不到"。</p>
<p><strong>修复两处：并列时放行（不剪），以及保护刚接上的新节点（保证至少一条入边）。</strong></p>
<h3>3.4 根因二：44 万个"幽灵"</h3>
<p>修完剪枝，召回只回到 0.85 左右。继续查，发现一个更严重的不一致：</p>
<p><code>HNSW 图内节点数        2,083,259</code><br>
<code>SQL 中有合法指纹的行数 1,638,397</code><br>
<code>差                      444,862</code></p>
<p>大量节点存在于 HNSW 里，SQL 侧却查不到对应的指纹。抽查发现这些"幽灵"的 SMILES 都是<strong>正常药物分子</strong>（阿司匹林类似物那一类），本该有指纹，不是脏数据。</p>
<p>根因是<strong>两个纯内存状态没有进快照</strong>：</p>
<ul>
<li><code>deleted_keys</code>：哪些向量已被逻辑删除（本应随索引落盘）；</li>
<li><code>doc_vectors</code>：哪些 id 当前持有有效向量。</li>
</ul>
<p>重启后这两个集合清零，于是删除过滤失效，历史被删节点重新漏进搜索结果；增量对账逻辑又因为"图里已经有这个节点"直接跳过，没去核对"它在文档侧其实已经没有指纹了"。搜索时的候选放大系数还写成了 <code>k + 已删数量</code>——44 万的删除量下，等于<strong>每次搜索都要扫全图</strong>。</p>
<p>泄漏路径的修复是 <strong>restore 后全量对账</strong>，把图内节点与文档侧做完整比对：</p>
<p><code>图有节点 + 文档有 fp        → noted        = 1,638,397  （重建 doc_vectors）</code><br>
<code>图有节点 + 文档无 fp / 行已删 → ghosts_marked = 444,862  （mark_deleted）</code><br>
<code>图无节点 + 文档有 fp        → 补录</code><br>
<code>合计                       = 2,083,259  = 图内节点数  ✓</code></p>
<p>随后执行<strong>原地 prune（非全量重建）</strong>：保留拓扑、全层邻居重写、双向边补全、entry/max_layer 重算，摘除 444,862 个节点耗时 <strong>23.1 秒</strong>（重建路径是小时级），快照从 959.8MB 瘦到 <strong>694.8MB（−27.6%）</strong>，<code>over_fetch</code> 从 8× 回落到 2×。</p>
<h3>3.5 根因三：四段失败链，不是一个 bug</h3>
<p>排查没有停在"对账修好了"。我们继续追"这些正常分子的 fp 为什么会变成 NULL"——这才是真正的源头。结论是<strong>四段失败叠加，任一段单独都不会出事故</strong>：</p>
<ol>
<li><strong>A · 导入用了不完整的 id 索引做 keyset 分页</strong>，导致分区断流，漏写约 65~78 万行的指纹；但导入日志显示的完成数约等于全表行数，当时以为已 100%。</li>
<li><strong>B · 覆盖率验证抽样偏差</strong>：<code>check_fp_coverage.py</code> 只抽查 7 个 id，<code>refill_gaps.py</code> 只查 CHEMBL1-9 前缀——全落在未漏写区域，<strong>假收口</strong>。</li>
<li><strong>C · chem 表批量导入的 INSERT 列清单不含 fp 列</strong>，新写入的版本覆盖了有 fp 的旧行，产生无 fp 的最新版本。</li>
<li><strong>D · pass-2 版本选择 bug</strong>（<code>w_seq == seq</code> 匹配 + <code>snapshot_sst_handles</code> 层序 L6→L0 反转）：向量 backfill 恰好跑在这个 bug 期间，层序从旧到新扫描、<code>seq</code> 被 <code>clean_index</code> 清零时读到了导入前的旧版本（有 fp），把旧版本指纹索引进图，而活版本无 fp——<strong>这就是 44.4 万差额的精确来源</strong>。</li>
</ol>
<p>这里有一个值得单独说的设计教训。我们这套索引的<strong>版本权威来自 LSM-Tree 的物理层序（newest-first + first-seen-wins），而不是</strong> <code>seq_no</code>。层序是存储引擎自己维护、不可篡改的事实；seq 是元数据，可以被重整、清零、碰撞。这个取舍在这次事故里救了我们——D 段的病灶正是"用 seq 代替层序"。</p>
<p><strong>生产端三条修复</strong>：pass-2 改走层序优先；<code>prune_ids</code> 按 id 去重（保留与 <code>doc_vectors</code> 匹配的那个，防止同 id 双节点一起存活）；chem 导入列清单补全 fp。覆盖率验证从 7 点抽查升级为"全量 COUNT + 分区分层抽样"。</p>
<p>排查过程中还顺带修掉 planner 一处结构性问题：<code>remaining_filter</code> 被包在 Limit 节点<strong>之上</strong>，计划形状是 <code>Filter(Limit(SeqScan))</code>，而 SQL 语义要求 <code>Limit(Filter(SeqScan))</code>——导致 <code>WHERE ... LIMIT N</code> 只返回 N−1 行，<code>ORDER BY ... LIMIT</code> 场景更是返回"错的行"而非"少的行"。</p>
<h3>3.6 结果</h3>
<p>最终验收采用 500 节点分层抽样（fp popcount 五分位 × 100）、GT 装载 1,638,397 条（与节点数逐位一致）：</p>
<table>
<thead>
<tr>
<th>指标</th>
<th>修复前</th>
<th>修复后（500 分层）</th>
</tr>
</thead>
<tbody>
<tr>
<td>id-recall@10</td>
<td>0.844</td>
<td><strong>0.9784</strong></td>
</tr>
<tr>
<td>dist-recall@10</td>
<td>0.848</td>
<td><strong>0.9964</strong></td>
</tr>
<tr>
<td>dist-recall@50</td>
<td>—</td>
<td><strong>0.9916</strong></td>
</tr>
<tr>
<td>id-recall@50</td>
<td>—</td>
<td><strong>0.9832</strong></td>
</tr>
<tr>
<td>倒挂幅度（@10 − @50）</td>
<td>0.044</td>
<td><strong>0.004</strong></td>
</tr>
<tr>
<td>self-recall（5000 样本）</td>
<td>1.00（小样本）</td>
<td><strong>0.9972</strong></td>
</tr>
<tr>
<td>幽灵命中（多查询点 TOP50）</td>
<td>18/50</td>
<td><strong>0 / 88</strong></td>
</tr>
<tr>
<td>快照体积</td>
<td>960MB</td>
<td><strong>695MB（−27.6%）</strong></td>
</tr>
<tr>
<td>over_fetch 放大</td>
<td>8×</td>
<td><strong>2×</strong></td>
</tr>
<tr>
<td>图节点数</td>
<td>2,083,259</td>
<td><strong>1,638,397（精确对齐 SQL）</strong></td>
</tr>
</tbody>
</table>
<p>所有闸门（id≥0.968 / dist@10≥0.990 / dist@50≥0.985 / self≥0.995 / ghost=0 / 节点数精确）全部通过。</p>
<h3>3.7 五个 bug，其实是同一类病</h3>
<p>这一路共修掉 5 个查询正确性 bug：equality 等值点查返回双行、ghost 泄漏、pass-2 版本选反、<code>NOT</code> 谓词被当成列名、以及 planner 的 Filter/Limit 形状错误。</p>
<p>它们底层是同一个病：<strong>"版本合流必须走层序、谓词归属必须覆盖所有算子形态"这条纪律，之前只在部分代码路径上落地了</strong>。修复方式不是逐个打补丁，而是<strong>收敛到一个公共迭代器</strong>——整族免疫，而不是这一次修好。</p>
<p>顺带记一条通用规则：凡输出顺序承载语义的路径（range 扫描、keyset 分页、层序扫描），去重一律用<strong>保序</strong>实现。我们最初给 equality 加去重时用了 <code>sort() + dedup()</code>，打乱了 range 的索引序，导致分页重复扫描、装载数虚高到 1.97M、召回掉到 0.76——换成保序去重后立刻恢复。</p>
<hr>
<h2>四、排查之后：从"人工深挖"到"自动发现"</h2>
<p>这次事故最值得反思的一点是：<strong>上述 5 个 bug，没有一个是监控发现的，全靠人工深挖。</strong> 修完 bug 只是第一步，第二步是让同类问题以后能被自动看见：</p>
<ul>
<li><strong>schema API 暴露向量索引状态</strong>：<code>nodes</code> / <code>deleted_keys</code> / <code>ready</code> / <code>m</code> / <code>ef_construction</code>，探针不再依赖日志格式。</li>
<li><strong>reconcile 日志分级告警</strong>：冷启动首次对账允许个位数 ghost（快照窗口内写入属正常）；冷启动后出现任何非零 → WARN；占比 &gt; 1% 建议 COMPACT；&gt; 10 万 → ERROR。</li>
<li><strong>独立探针拆分</strong>：<code>probe_vec_nodes.py</code> / <code>probe_vec_ghost.py</code> / <code>probe_vec_self.py</code>（秒级健康检查）/ <code>probe_ready_gate.py</code>（启动窗口负向探针），各自可跑。</li>
<li><strong>启动门闩</strong>：对账完成前向量查询返回明确错误，而不是静默返回脏结果——用约 28 秒的"等待可用"换"不返回错数据"。</li>
<li><strong>k8s 探针拆分</strong>：liveness 立即返回 200，readiness 等待 <code>ready=true</code>，避免对账未完成时探针失败触发无限重启循环。</li>
</ul>
<hr>
<h2>五、共建与邀约</h2>
<p>OntoDB 核心内核以<strong>开源生态层 + 闭源企业能力</strong>双轨推进。我们想找的是：</p>
<ul>
<li>在真实场景里用得上"向量 + 图 + 本体 + 流"的团队——<strong>来仓库提 Issue 聊场景，哪怕是"你这个设计在我的场景下不成立"这种</strong>；</li>
<li>愿意补 client SDK、文档、查询算子的同学——<code>crates/</code> 下每个 crate 边界写得比较清楚，PR 门槛不高；</li>
<li>想写点东西的人——欢迎写"我用 OntoDB 接了哪个 Agent、哪张知识图谱"，踩坑文比赞美文受欢迎得多。</li>
</ul>
<p><strong>给评论区留一个我们确实没想透的问题：</strong></p>
<blockquote>
<p>在离散距离空间（二进制指纹、量化嵌入）里，HNSW 的多样性剪枝该怎么处理"并列距离"？并列放行，还是引入第二判据（比如按层序或 id 稳定排序）？你们的实现是怎么处理的，有没有踩过类似的坑？</p>
</blockquote>
<p>仓库在这里，欢迎 clone、跑 Demo、开 Issue：</p>
<p><strong>https://github.com/jianzhuguo/ontodb</strong></p>
<p><code># 前置：Rust 1.77+</code><br>
<code>git clone https://github.com/jianzhuguo/ontodb.git</code><br>
<code>cd ontodb</code><br>
<code>cargo build --release</code><br>
<code>./target/release/ontodb-server --data-dir ./data --http 0.0.0.0:7912</code></p>
<hr>
<h2>六、In Rust We Trust</h2>
<p>谢谢 Rust 中文社区，谢谢各位Ruster，我们产品已经开源发布，现在轮到社区来用、来骂、来改、来共建。</p>
<hr>
<p>*（本文性能数字与故障复盘均来自仓库基准报告与真实排查记录；最终验收采用 500 节点分层抽样与 5000 节点 self-recall 验证。未覆盖项——并发压测、kill-9 崩溃注入、千万级规模边界、*<code>deleted_keys/doc_vectors</code> <em>持久化——不在本文宣称范围内，不做隐藏。）</em></p>
]]></description><pubDate>2026-10-21 03:17:29</pubDate></item><item><title>【RPI 更新】把 rpi Agent 装进你的zed 编辑器</title><link>https://rustcc.cn/article?id=4dd995ce-b5ee-4e94-a883-d4b2a532c25f</link><description><![CDATA[<h2>架构</h2>
<pre><code>Zed  ──ACP (JSON-RPC over stdio)──▶  rpi --acp  ──spawn──▶  rpi --mode rpc  (每会话一个)
</code></pre>
<p><code>rpi-acp</code> 是个 cdylib 扩展，做三件事：<strong>抢 stdio</strong>、<strong>说 ACP v1</strong>、<strong>给每个会话挂一个 <code>rpi --mode rpc</code> 子进程</strong>。桥接层自己不跑模型——tools、models、auth、skills 全在子进程里，所以行为跟终端里跑 rpi 完全一致。</p>
<h2>关键机制：抢夺 stdio</h2>
<p>宿主默认会 drain stdin，扩展就拿不到 stdio，ACP server 无从谈起。解法：带 <code>--acp</code> 时，扩展在注册阶段声明 <code>{"ownsStdio": true}</code>，宿主随即停止 drain，改走 <code>StdioLifecycle</code>，把 stdin/stdout 交给扩展。</p>
<p>从终端直接跑 <code>--acp</code> 会<strong>快速失败</strong>（一条消息 + exit 2），而不是空转。要注册用 <code>rpi --install-zed</code>。</p>
<h2>事件映射</h2>
<table>
<thead>
<tr>
<th>rpi RPC 事件</th>
<th>ACP update</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>text_delta</code> / <code>thinking_delta</code></td>
<td><code>agent_message_chunk</code> / <code>agent_thought_chunk</code></td>
</tr>
<tr>
<td><code>tool_execution_start</code></td>
<td><code>tool_call</code>（edit/write 带 diff）</td>
</tr>
<tr>
<td><code>tool_execution_update</code> / <code>_end</code></td>
<td><code>tool_call_update</code></td>
</tr>
<tr>
<td><code>plan_mode_complete</code></td>
<td><code>plan</code></td>
</tr>
<tr>
<td>outcome aborted / completed</td>
<td><code>stopReason: cancelled</code> / <code>end_turn</code></td>
</tr>
</tbody>
</table>
<p>流式文本用<strong>累积快照 + finalText</strong> 去重，不重发已发过的 chunk。</p>
<h2>会话持久化</h2>
<p>稳定 UUID，原生 JSONL 历史落在 <code>~/.rpi/agent/acp/sessions</code>（可用 <code>RPI_ACP_SESSION_DIR</code> 覆盖），进程退出后仍在。<code>session/load</code> 恢复并<strong>重放</strong>，<code>session/resume</code> 恢复但<strong>不重放</strong>。未知会话<strong>返回错误</strong>，不静默开空对话。</p>
<h2>权限与问题扩展</h2>
<ul>
<li><strong>权限</strong>：插件弹窗（如 bash 确认）映射成标准 <code>session/request_permission</code>，用户选择回传插件。默认带 <code>--permission-gate</code>。</li>
<li><strong>问题</strong>：ACP v1 没有通用多选方法，于是双方在 <code>initialize</code> 里用 <code>_meta: {"pi-rust/questions": 1}</code> 协商。只有广告了 v1 的客户端才收到 <code>_rpi/request_question</code>；超时默认 300s，配套 <code>_rpi/dialog_closed</code> 通知回收 UI。</li>
</ul>
<h2>安装配置</h2>
<pre><code>rpi install rpi-acp    # 或 task install
</code></pre>
<p>Zed <code>settings.json</code>：</p>
<pre><code>{ "agent_servers": { "rpi": { "type": "custom", "command": "rpi", "args": ["--acp"] } } }
</code></pre>
<p><code>args</code> 可透传普通 flag，如 <code>["--acp", "--model", "gateway/model"]</code>。<code>--acp</code> 会自动注册到 Zed（幂等、原子写、保留 JSONC 注释）；设 <code>RPI_ACP_NO_AUTO_REGISTER_ZED=1</code> 可关掉。</p>
<h2>独立二进制 <code>rpi-acp-bridge</code></h2>
<p>同样的 server 也能编成独立二进制，<strong>原生拥有 stdin/stdout</strong>，不需要 <code>ownsStdio</code>，可直接对着 stock rpi 跑。找 agent 的顺序：<code>RPI_BIN</code> → 自身 → 兄弟文件 → PATH。</p>
<pre><code>cargo build --release -p rpi-acp --bin rpi-acp-bridge
task pack-acp   # 打包进 ACP Registry
</code></pre>
<p>相关链接</p>
<ul>
<li>🏠 官网与文档：<a href="https://rpi.laofu.online/" rel="noopener noreferrer">https://rpi.laofu.online/</a></li>
<li>📦 核心仓库：<a href="https://github.com/bigfish1913/pi-rust" rel="noopener noreferrer">bigfish1913/pi-rust</a></li>
<li>🔌 扩展仓库：<a href="https://github.com/pi-rust/rpi-package" rel="noopener noreferrer">pi-rust/rpi-package</a></li>
<li>📚 软件包目录：<a href="https://rpi.laofu.online/packages.html" rel="noopener noreferrer">https://rpi.laofu.online/packages.html</a></li>
<li>✍️ 个人博客：<a href="https://blog.laofu.online/" rel="noopener noreferrer">https://blog.laofu.online/</a></li>
</ul>
]]></description><pubDate>2026-10-14 15:51:34</pubDate></item><item><title>Ramag v0.0.2 发布：新增 SSH、SFTP 与 JumpServer 导入</title><link>https://rustcc.cn/article?id=691353be-7377-4388-86ac-edd20b706443</link><description><![CDATA[<p>Ramag 是一个使用 Rust + GPUI 构建的本地优先开发者桌面工作台，将数据库、Git、SSH 和剪贴板放进同一个原生应用。</p>
<pre><code>数据库 ↔ Git ↔ SSH / SFTP ↔ 剪贴板
</code></pre>
<ul>
<li>GitHub：https://github.com/tools-rs/ramag</li>
<li>下载：https://github.com/tools-rs/ramag/releases/tag/v0.0.2</li>
<li>更新记录：https://github.com/tools-rs/ramag/blob/main/CHANGELOG.md</li>
</ul>
<p><img src="https://cdn.jsdelivr.net/gh/tools-rs/ramag@main/docs/screenshots/v0.0.2/home-light.png" alt="Ramag v0.0.2 首页"></p>
<h2>v0.0.2 主要更新</h2>
<h3>SSH 连接管理</h3>
<p>新增完整的 SSH 管理入口，支持：</p>
<ul>
<li>密码、系统 SSH 配置和密钥认证</li>
<li>解析 <code>ssh user@host -p 2222 -i /path/to/key</code> 命令</li>
<li>连接测试、默认目录和生产连接标记</li>
<li>多连接标签和连接搜索</li>
<li>本机加密保存密码与敏感连接参数</li>
</ul>
<p>终端连接复用系统 OpenSSH，因此可以继续使用现有的 <code>~/.ssh/config</code>、SSH Agent、密钥和 <code>known_hosts</code>。</p>
<p><img src="https://cdn.jsdelivr.net/gh/tools-rs/ramag@main/docs/screenshots/v0.0.2/ssh-connections-empty-light.png" alt="SSH 连接管理"></p>
<h3>内嵌终端与 SFTP 文件工作区</h3>
<p>连接成功后，可以在同一个工作区中使用内嵌终端和远程文件浏览：</p>
<ul>
<li>ANSI 终端显示和常用键盘输入</li>
<li>一个连接下打开多个终端标签</li>
<li>始终保留至少一个终端，避免误关后留下空页面</li>
<li>远程目录浏览、路径导航和名称搜索</li>
<li>文本预览与编辑、日志跟随</li>
<li>文件和目录上传下载</li>
<li>覆盖确认、取消和传输进度</li>
</ul>
<p>还可以从当前路径、目录或文件所在位置创建新终端。新终端会进入对应远程目录，不影响已有终端的运行状态。</p>
<p>生产连接会禁止 SFTP 上传、编辑、重命名和删除。终端命令仍由远端账号权限与服务器策略约束。</p>
<p><img src="https://cdn.jsdelivr.net/gh/tools-rs/ramag@main/docs/screenshots/v0.0.2/ssh-workspace-light.png" alt="SSH 内嵌终端与远程文件工作区"></p>
<h3>JumpServer 导入</h3>
<p>支持保存多个 JumpServer 登录，并直接读取：</p>
<ul>
<li>组织与资产树</li>
<li>已授权资产</li>
<li>资产平台和地址</li>
<li>可用的授权账号</li>
</ul>
<p>选择资产与授权账号后，可以导入为普通 SSH 连接，继续编辑、测试和打开。未开放 SSH 协议的资产会明确提示，不会错误导入。</p>
<h3>数据库改进</h3>
<ul>
<li>结果搜索支持字符串 ID 与整数 ID 双向转换。</li>
<li>内置 Base10、Base16、Base36、Base58 Bitcoin、Base58 Flickr 和自定义字符表。</li>
<li>支持带路径、超时和输出限制的外部转换器。</li>
<li>修复 MySQL <code>SHOW WARNINGS</code> 被识别为普通分页查询的问题。</li>
<li>数据库连接导入导出迁移到全局设置，可统一处理 MySQL、PostgreSQL、Redis 和 MongoDB。</li>
<li>编辑连接时完整回填现有参数，生产连接继续受只读保护。</li>
</ul>
<h3>Git 与剪贴板改进</h3>
<p>Git 工作台新增明确的克隆入口，Markdown 文件默认渲染预览，并重新整理了分支、远端、Tag 和 Stash 操作。同时修复新建分支导致的界面崩溃、分栏宽度串联和部分标签无法通过 <code>⌘W</code> / <code>Ctrl+W</code> 关闭的问题。</p>
<p>剪贴板仍默认关闭。启用状态、采集行为、全局热键和“清空全部历史”统一迁移到全局设置；关闭后会隐藏入口并释放全局快捷键。</p>
<pre><code>macOS：⌘⇧V
Windows：Ctrl+Shift+V
</code></pre>
<h2>本地优先与安全边界</h2>
<p>Ramag 不要求登录账号，也不会把数据库连接、SSH 凭据、Git 仓库或剪贴板内容上传到 Ramag 服务。</p>
<ul>
<li>敏感配置使用 AES-256-GCM 加密。</li>
<li>主密钥保存在 macOS Keychain 或 Windows Credential Manager。</li>
<li>SSH 认证、主机校验和 Git 网络操作复用系统已有配置。</li>
<li>数据库和 SSH 生产连接会限制界面中的写操作。</li>
</ul>
<p>Git 功能仍处于试验阶段。生产数据库操作、Git 写操作和远程终端命令仍需要使用者确认目标环境和影响范围。</p>
<h2>下载</h2>
<p>v0.0.2 Release：</p>
<p>https://github.com/tools-rs/ramag/releases/tag/v0.0.2</p>
<p>当前提供：</p>
<pre><code>Ramag-0.0.2-macos-arm64.dmg
Ramag-0.0.2-macos-x86_64.dmg
Ramag-0.0.2-windows-x64-setup.exe
SHA256SUMS.txt
</code></pre>
<p>支持 macOS 12+ Apple Silicon、macOS 12+ Intel 和 Windows 10/11 x64，暂不支持 Linux。</p>
<p>当前 Windows 安装包尚未做 Authenticode 签名，macOS 安装包尚未完成 Developer ID 签名与 Apple 公证。请只从项目 Releases 下载，并使用同一页面的 <code>SHA256SUMS.txt</code> 校验文件。</p>
<p>从源码运行：</p>
<pre><code>git clone https://github.com/tools-rs/ramag.git
cd ramag
make develop
</code></pre>
<p>如果你正在使用 Rust、GPUI、数据库工具或 SSH/SFTP 工作流，欢迎下载体验。遇到问题时，可以在 GitHub Issues 中附上操作系统、Ramag 版本和复现步骤；提交前请删除服务器地址、用户名、密码和业务数据。</p>
<ul>
<li>Issues：https://github.com/tools-rs/ramag/issues</li>
<li>源码：https://github.com/tools-rs/ramag</li>
</ul>
]]></description><pubDate>2026-08-04 09:46:17</pubDate></item><item><title>GitBundle v3.5</title><link>https://rustcc.cn/article?id=4f9a98e9-2ea8-4029-b455-1da1e040702a</link><description><![CDATA[<p>大家好, 我是一名独立开发者, 同时也是 <a href="https://github.com/gitbundle/gitbundle" rel="noopener noreferrer">GitBundle</a> 的项目作者, 在这个项目上持续投入了巨量的时间和精力, 经过持续的迭代和打磨，GitBundle 终于迎来了 v3.5 版本。这次更新在安全性、CI 交互和用户体验上都做了重点提升，希望给大家带来更好的自托管 Git 体验。</p>
<p>🔐 安全性大幅增强</p>
<ul>
<li>移除 SHA-1，新增 SSH layer，支持后量子密钥交换算法 mlkem768x25519，彻底修复 SSH 安全警告</li>
<li>修复了 git clone 无法安全断开 TCP 连接的问题</li>
</ul>
<p>⚙️ 后台管理优化</p>
<ul>
<li>支持用户软删除，数据管理更灵活</li>
<li>支持用户安全更新邮箱</li>
</ul>
<p>🚀 CI 与体验提升</p>
<ul>
<li>支持 cursor-based CI 日志拉取，交互更顺畅</li>
<li>UI 全面打磨，修复了多项历史遗留问题，视觉和操作更一致流畅</li>
</ul>
<p>为什么要做这个项目:
第一点: 肯定是因为兴趣爱好, 因为我喜欢写代码, 喜欢做这个事情
第二点: 我见识过类似的各种平台, 但都是差强人意, 体验很糟糕
第三点: 的的确确我找不到工作, 失业了, 职场远远不是你想写代码那么简单, 这是一个很痛的现实, 但我必须要接受, 因为我还想继续写代码直到写不动的那一天, 可现实不允许我这样</p>
<p>欢迎大家下载试用，也期待大家的反馈和建议！ 🙏</p>
<p>关于大家关心的源代码开源问题, 目前有计划在将来进行开源, 但具体开源时间还不确定.</p>
<p>详细发布日志:</p>
<p>https://github.com/gitbundle/gitbundle/releases/tag/server-v3.5.0</p>
]]></description><pubDate>2026-06-11 11:48:16</pubDate></item><item><title>A high-performance async Rust implementation of KCP - A Fast and Reliable ARQ Protocol built on top of Tokio.</title><link>https://rustcc.cn/article?id=29969d7b-6ba8-4f9e-908c-4004a893fee0</link><description><![CDATA[<p>https://github.com/leihuxi/rust-kcp
A high-performance async Rust implementation of KCP - A Fast and Reliable ARQ Protocol built on top of Tokio.</p>
<p>Features
Async-First Design: Built from ground up for async/await with Tokio integration
Zero-Copy: Efficient buffer management using the bytes crate
Lock-Free Buffer Pool: High-performance memory management with crossbeam
Connection-Oriented: High-level connection abstractions (KcpStream, KcpListener)
Protocol Compatible: Compatible with original C KCP implementation
Observability: Integrated tracing and metrics support
Memory Efficient: Object pooling and buffer reuse
Multiple Performance Modes: Normal, Fast, Turbo, Gaming presets
Installation
Add this to your Cargo.toml:</p>
<p>[dependencies]
kcp-tokio = "0.4"
tokio = { version = "1.0", features = ["full"] }
Quick Start
Client
use kcp_tokio::{KcpConfig, KcpStream};
use tokio::io::{AsyncReadExt, AsyncWriteExt};</p>
<p>#[tokio::main]
async fn main() -&gt; Result&lt;(), Box&gt; {
let config = KcpConfig::new().fast_mode();
let mut stream = KcpStream::connect("127.0.0.1:12345".parse()?, config).await?;</p>
<pre><code>// Send data
stream.write_all(b"Hello, KCP!").await?;

// Receive response
let mut buffer = [0u8; 1024];
let n = stream.read(&amp;mut buffer).await?;
println!("Received: {}", String::from_utf8_lossy(&amp;buffer[..n]));

Ok(())
</code></pre>
<p>}
Server
use kcp_tokio::{KcpConfig, KcpListener};
use tokio::io::{AsyncReadExt, AsyncWriteExt};</p>
<p>#[tokio::main]
async fn main() -&gt; Result&lt;(), Box&gt; {
let config = KcpConfig::realtime();
let mut listener = KcpListener::bind("127.0.0.1:12345".parse()?, config).await?;</p>
<pre><code>println!("Server listening on 127.0.0.1:12345");

while let Ok((mut stream, addr)) = listener.accept().await {
    println!("New connection from {}", addr);
    tokio::spawn(async move {
        let mut buf = [0u8; 1024];
        while let Ok(n) = stream.read(&amp;mut buf).await {
            if n == 0 { break; }
            let _ = stream.write_all(&amp;buf[..n]).await;
        }
    });
}

Ok(())
</code></pre>
<p>}
Architecture
┌─────────────────────────────────────────────────────────────┐
│                    Application Layer                         │
│              (User code using KcpStream/KcpListener)         │
├─────────────────────────────────────────────────────────────┤
│                    High-Level API Layer                      │
│                  KcpStream    KcpListener                    │
│           (AsyncRead/AsyncWrite, TCP-like interface)         │
├─────────────────────────────────────────────────────────────┤
│                    Protocol Core Layer                       │
│                       KcpEngine                              │
│        (ARQ logic, congestion control, retransmission)       │
├─────────────────────────────────────────────────────────────┤
│                    Common Layer                              │
│         KcpSegment, KcpHeader, BufferPool, Constants         │
├─────────────────────────────────────────────────────────────┤
│                    Transport Layer                           │
│          Generic Transport trait (UDP default)               │
└─────────────────────────────────────────────────────────────┘
Configuration
Performance Presets
// Gaming - ultra-low latency (3ms update interval)
let config = KcpConfig::gaming();</p>
<p>// Real-time communication (8ms update interval)
let config = KcpConfig::realtime();</p>
<p>// File transfer - high throughput
let config = KcpConfig::file_transfer();</p>
<p>// Testing with packet loss simulation
let config = KcpConfig::testing(0.1); // 10% packet loss
Performance Modes
Mode	Update Interval	Resend	Congestion Control	Use Case
Normal	40ms	0	Yes	General purpose
Fast	8ms	2	Yes	Low latency
Turbo	4ms	1	No	Maximum speed
Gaming	3ms	1	No	Real-time games
Custom Configuration
use std::time::Duration;</p>
<p>let config = KcpConfig::new()
.fast_mode()
.window_size(128, 128)
.mtu(1400)
.connect_timeout(Duration::from_secs(10))
.keep_alive(Some(Duration::from_secs(30)))
.stream_mode(true);
Examples</p>
<h1>Run performance test server</h1>
<p>cargo run --example perf_test_server -- 127.0.0.1:12345 gaming</p>
<h1>Run performance test client</h1>
<p>cargo run --example perf_test_client -- 127.0.0.1:12345</p>
<h1>Run simple echo example</h1>
<p>cargo run --example simple_echo
Testing</p>
<h1>Run all tests</h1>
<p>cargo test</p>
<h1>Run resilience tests (packet loss, reorder, concurrent connections)</h1>
<p>cargo test --test resilience_test</p>
<h1>Run benchmarks</h1>
<p>cargo bench</p>
<h1>Run with logging</h1>
<p>RUST_LOG=debug cargo test -- --nocapture</p>
<h1>Run clippy</h1>
<p>cargo clippy --all-targets -- --deny clippy::all
Documentation
Detailed documentation is available in the doc/ directory:</p>
<p>Document	Description
ARCHITECTURE.md	System architecture and design
MODULES.md	Module reference and APIs
USAGE.md	Usage guide and examples
TESTING.md	Testing guide
Performance
KCP provides significant latency improvements over TCP:</p>
<p>30-40% lower latency in typical network conditions
Better performance on lossy networks
Configurable trade-offs between latency and bandwidth
Optimizations in this Implementation
Actor-based lock-free architecture: KcpEngine runs in a single dedicated tokio task, eliminating Arc&lt;Mutex&lt;&gt;&gt; contention
Generic Transport trait: Associated Addr type with RPITIT — zero heap allocation on hot path (no Pin&lt;Box&gt;)
DashMap for packet routing: Listener uses lock-free concurrent hashmap on the hot path
Lock-free buffer pools: crossbeam::queue::ArrayQueue for zero-allocation fast path
BTreeMap receive buffer: O(log n) insertion for out-of-order packets (vs O(n) linear scan)
Zero-copy segment encoding: Flush avoids cloning segments, encodes by reference
Cached timestamps: Single syscall per input() call instead of 3+
Pre-allocated buffers: VecDeque::with_capacity based on window sizes, avoiding grow overhead on send burst
Zero-copy packet handling with bytes crate
Grouped state structs for better cache locality
Configurable update intervals (3-40ms)
Batch ACK processing
Use Cases
Gaming: Ultra-low latency for real-time multiplayer
VoIP/Video: Real-time communication
Live Streaming: Low-latency data delivery
File Transfer: Reliable bulk data transfer
IoT: Efficient communication for constrained devices
Compatibility
Protocol: Compatible with original C KCP
Rust: Edition 2021, stable toolchain
Tokio: 1.0+
License
MIT License - see LICENSE file.</p>
<p>Contributing
Contributions are welcome! Please feel free to submit a Pull Request.</p>
<p>Resources
Original KCP Protocol
KCP Protocol Documentation
Tokio Documentation
Benchmarks
Criterion benchmarks measure engine-level throughput and latency:</p>
<p>cargo bench
Benchmark	Description
engine_throughput	10/100/500 x 1KB messages
engine_small_messages	1000 x 64B messages
engine_large_message	Single 16KB/64KB message fragmentation + reassembly
Version History
v0.4.0: Extract kcp-core as standalone protocol crate, restructure source layout (src/ → kcp/, flatten async_kcp/)
v0.3.7: Fix ACK window/UNA fields, generic Transport trait with RPITIT, resilience tests, criterion benchmarks
v0.3.4: Engine refactoring, lock-free buffer pools, documentation
v0.3.3: Performance optimizations, sub-millisecond latency
v0.3.1: Full async support, comprehensive configuration
v0.2.x: Performance improvements and bug fixes
v0.1.x: Initial implementation</p>
]]></description><pubDate>2026-05-11 07:11:35</pubDate></item><item><title>mace：又一个嵌入式 key-value 存储</title><link>https://rustcc.cn/article?id=e2ec9976-8f93-4c2e-b63e-5d4419f55631</link><description><![CDATA[<p>mace 是一个 Rust 实现的嵌入式 KV 引擎，结合了 B+ 树的读性能和 LSM 树的写吞吐，在读多写少和扫描场景下有明显的性能优势。</p>
<hr>
<h2>核心能力</h2>
<ul>
<li><strong>混合架构</strong>：兼顾 B+ 树读速与 LSM 树写吞吐</li>
<li><strong>MVCC 并发</strong>：非阻塞的并发读写</li>
<li><strong>闪存优化</strong>：面向 SSD/NVMe 的 log-structured 设计</li>
<li><strong>大值分离</strong>：独立 Blob 存储，减少写放大</li>
<li><strong>ACID 事务</strong>：完整的事务支持</li>
</ul>
<hr>
<h2>性能数据</h2>
<table>
<thead>
<tr>
<th>场景</th>
<th>吞吐量提升</th>
</tr>
</thead>
<tbody>
<tr>
<td>随机读</td>
<td>2.4x</td>
</tr>
<tr>
<td>范围扫描</td>
<td>3.5x</td>
</tr>
<tr>
<td>读 heavy 混合负载</td>
<td>2.3x</td>
</tr>
<tr>
<td>写 heavy 混合负载</td>
<td>0.76x</td>
</tr>
</tbody>
</table>
<blockquote>
<p>注：以上为与 RocksDB 对比的中位数倍数。</p>
</blockquote>
<hr>
<h2>适用场景</h2>
<ul>
<li>需要高并发读写的嵌入式服务（尤其是 mixed/read-heavy 负载）</li>
<li>写入吞吐敏感的本地存储层（中小 value 场景优势更明显）</li>
<li>混合读写 + 扫描的业务</li>
<li>需要本地事务和 MVCC 的 Rust 应用</li>
</ul>
<hr>
<h2>地址</h2>
<ul>
<li>源码：<a href="https://github.com/abbycin/mace" rel="noopener noreferrer">https://github.com/abbycin/mace</a></li>
<li>Benchmark 脚本：<a href="https://github.com/abbycin/kv_bench" rel="noopener noreferrer">https://github.com/abbycin/kv_bench（scale 分支）</a></li>
</ul>
<blockquote>
<p>mace 还在非常早期的阶段，目前还在努力提升稳定性以及对特定workload进行优化...</p>
</blockquote>
<p><strong>0.0.29 版更新</strong></p>
<table>
<thead>
<tr>
<th>Workload</th>
<th align="right">Mace胜OPS</th>
<th align="right">OPS中位数比 (Mace/RocksDB)</th>
<th align="right">Mace胜p99</th>
<th align="right">p99中位数比 (Mace/RocksDB)</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>W1</code> (95R/5U, uniform)</td>
<td align="right">16 / 16</td>
<td align="right"><strong>2.3x</strong></td>
<td align="right">5 / 16</td>
<td align="right"><strong>1.0x</strong></td>
</tr>
<tr>
<td><code>W2</code> (95R/5U, zipf)</td>
<td align="right">16 / 16</td>
<td align="right"><strong>1.5x</strong></td>
<td align="right">11 / 16</td>
<td align="right"><strong>0.5x</strong></td>
</tr>
<tr>
<td><code>W3</code> (50R/50U)</td>
<td align="right">15 / 16</td>
<td align="right"><strong>1.4x</strong></td>
<td align="right">9 / 16</td>
<td align="right"><strong>0.5x</strong></td>
</tr>
<tr>
<td><code>W4</code> (5R/95U)</td>
<td align="right">12 / 16</td>
<td align="right"><strong>1.3x</strong></td>
<td align="right">7 / 16</td>
<td align="right"><strong>1.0x</strong></td>
</tr>
<tr>
<td><code>W5</code> (70R/25U/5S)</td>
<td align="right">15 / 16</td>
<td align="right"><strong>2.1x</strong></td>
<td align="right">16 / 16</td>
<td align="right"><strong>0.2x</strong></td>
</tr>
<tr>
<td><code>W6</code> (100% scan)</td>
<td align="right">16 / 16</td>
<td align="right"><strong>4.6x</strong></td>
<td align="right">15 / 16</td>
<td align="right"><strong>0.2x</strong></td>
</tr>
</tbody>
</table>
]]></description><pubDate>2026-03-09 11:56:39</pubDate></item><item><title>🌱 Rudis 0.4.0 发布，一个高性能内存数据库</title><link>https://rustcc.cn/article?id=682d0f5e-15ec-4138-aff6-d045fb529a7e</link><description><![CDATA[<p>项目介绍：</p>
<p>Rudis 是一个采用 Rust 语言编写得高性能键值存储系统，旨在利用 Rust 语言的优势来重新复现 Rudis 的核心功能，以满足用户对高性能、可靠性和安全性的需求，同时保证与 Rudis API 的兼容。</p>
<p>跨平台，兼容 windows、linux 系统架构。 兼容 字符串、集合、哈希、列表、有序集合数据结构。 提供 rdb 与 aof 机制以支持数据备份和恢复。 拥有卓越的处理速度和即时响应能力。 兼容 Rudis 的命令和协议规范。</p>
<p>欢迎在 GitHub 上关注我们的项目发展轨迹：</p>
<p>👉 https://github.com/lunar-landing/rudis</p>
<p>更新日志：</p>
<ul>
<li>新增 List 数据结构 Blpop、Brpop 命名。</li>
<li>新增 Hash 数据结构 HSCAN 命令，支持 MATCH 和 COUNT 参数。</li>
<li>新增 String 数据结构 SETEX、PSETEX、SETNX、SETBIT、GETBIT、BITCOUNT、BITOP 命令。</li>
<li>新增 Set 数据结构 SRANDMEMBER、SDIFFSTORE、SINTERSTORE、SMOVE 命令。</li>
<li>新增 HyperLogLog 数据结构及 PFADD、PFCOUNT、PFMERGE 命令。</li>
<li>重构 SortedSet 底层实现，采用 HashMap + SkipList 架构提升性能，并支持 bincode 序列化。</li>
<li>修复 SETEX/PSETEX 过期记录清理逻辑以及系统时间倒退导致的 RDB 调度 Panic 问题。</li>
</ul>
]]></description><pubDate>2026-02-03 03:12:19</pubDate></item><item><title>我做了一个独立开发者行情板，想试着对抗一次内卷</title><link>https://rustcc.cn/article?id=7a4bcdcd-4650-425b-92a4-6ef65838534b</link><description><![CDATA[<h1>接私活这几年，我发现我们根本不知道「合理报价」是多少</h1>
<p>这几年接私活、做外包、做独立项目，有一个问题一直困扰我：</p>
<blockquote>
<p><strong>我们其实不知道一个项目「合理的价格」是多少。</strong></p>
</blockquote>
<p>不是技术难度不知道，而是——<br>
你不知道别人真实成交是多少，只能靠猜、靠平台最低价、靠「听说」。</p>
<p>需求方会说：</p>
<blockquote>
<p>「别人比你便宜一半。」</p>
</blockquote>
<p>开发者只能纠结：</p>
<blockquote>
<p>「我是报高了，还是别人报低了？」</p>
</blockquote>
<p>时间久了，就变成大家都在往下试探，<br>
<strong>内卷不是某个人的选择，而是信息不透明的结果。</strong></p>
<hr>
<h2>我已经做了什么</h2>
<p>我先从自己开始。</p>
<p>我把自己这几年做过的一些真实项目整理出来，包括：</p>
<ul>
<li>项目类型</li>
<li>实际成交价格</li>
<li>大概工期</li>
<li>是否反复改需求</li>
<li>是否包含售后</li>
</ul>
<p>做成了一个 <strong>独立开发者行情板</strong>。</p>
<p>目前一共 <strong>23 个案例</strong>：</p>
<ul>
<li>大部分是我自己的真实成交</li>
<li>少部分是朋友的</li>
<li>也有几个是匿名提交的</li>
</ul>
<p>我不回避这个事实：<br>
<strong>数据现在还很少，而且并不「漂亮」。</strong></p>
<p>但它至少是真实的。</p>
<hr>
<h2>为什么我需要更多人，而不是「更多数据」</h2>
<p>我一个人的案例，其实没什么意义。</p>
<p>但如果有：</p>
<ul>
<li>50 个</li>
<li>100 个</li>
<li>200 个</li>
</ul>
<p>来自不同背景、不同技术栈、不同城市的真实案例，<br>
至少可以做到一件事：</p>
<blockquote>
<p><strong>让后来的人，在报价时有一个不被平台最低价绑架的参考。</strong></p>
</blockquote>
<p>你不需要证明你多厉害，<br>
也不需要报一个「体面」的价格，<br>
<strong>真实比好看重要。</strong></p>
<hr>
<h2>关于匿名和安全</h2>
<p>我知道大家最担心什么，所以我一开始就做了两件事：</p>
<ul>
<li>提供 <strong>匿名提交</strong></li>
<li>不要求任何可追溯身份信息</li>
</ul>
<p>目前有两个入口：</p>
<p><a href="https://test-cigsro9bfq3z.feishu.cn/share/base/form/shrcnoJFwnYGX1E8NKW6qjpNJ6X?from=navigation" rel="noopener noreferrer">飞书表单</a>
<a href="https://market.fxlogo.site" rel="noopener noreferrer">行情板网站</a></p>
<p>不署名、不展示来源、不做商业售卖。<br>
你可以只写你愿意写的字段。</p>
<hr>
<h2>说一句更远一点的想法（不画饼）</h2>
<p>行情板不是终点。</p>
<p>我真正想做的，是一个 <strong>不竞价、不抽佣、不负责售后</strong> 的撮合平台，<br>
只做一件事：</p>
<blockquote>
<p><strong>把预算真实的需求方，和愿意按合理价格做事的开发者，匹配到一起。</strong></p>
</blockquote>
<p>行情板只是前战，是定价共识的基础。<br>
如果连「合理价格区间」都没有，<br>
任何撮合都会退化成比谁便宜。</p>
<p>我不确定这条路能走多远，<br>
但至少想先试一次。</p>
<hr>
<h2>最后</h2>
<p>如果你愿意贡献一个案例：</p>
<ul>
<li>成功的</li>
<li>失败的</li>
<li>觉得自己报低了的</li>
<li>或者被压价压得很难受的</li>
</ul>
<p>都可以。</p>
<p>如果你不想提交，也没关系，<br>
<strong>至少希望这个东西能让你下次报价时，心里多一点底气。</strong></p>
]]></description><pubDate>2026-02-02 10:25:00</pubDate></item><item><title>低成本 AI 赋能首选！算纽 GPUNexus 聚合全球算力，MaaS 服务直达业务核心</title><link>https://rustcc.cn/article?id=d599b7f7-9c0b-4fe6-8396-133b85abbe30</link><description><![CDATA[<p>算纽GPUNexus定位全球 GPU 资源智能调度枢纽，致力于构建低成本、高弹性的下一代分布式 AI 计算生态。我们的核心服务模式：</p>
<ul>
<li>
<p>算力层聚合：广泛接入全球闲散 GPU 算力资源，通过标准化调度技术实现算力的统一管理与高效利用；</p>
</li>
<li>
<p>服务层赋能：在聚合算力之上深度部署 MaaS 模型服务，客户无需投入高昂成本搭建算力与模型架构，只需通过简洁的大模型接口，即可按需调用 AI 能力，快速赋能业务创新。</p>
</li>
</ul>
<p>算纽（GPUNexus）打通算力资源与模型应用的壁垒，让 AI 服务更便捷、更普惠。</p>
<h1>2. 产品形态</h1>
<h2>2.1. 算力资产分享</h2>
<p>算纽算力资产分享产品，核心打破算力孤岛，依托智能调度技术，实现各类计算资源一键接入、整合与统一调度，激活分散算力价值。</p>
<p>产品支持全场景接入，覆盖算力中心、企业服务器等专业设备及个人电脑、手机等终端，实现“云-边-端”全域覆盖。无论闲置算力拥有方（企业/机构/个人）还是算力需求方，均可通过平台精准匹配、高效流转。</p>
<p>无需复杂配置即可快速上线，智能调度实现供需实时匹配，既提升算力利用率，又帮助需求方降本、分享方变现，构建互利共赢的算力生态。</p>
<h2>2.2. MAAS服务</h2>
<p>算纽 MaaS服务，一站式整合30 余款主流开源大模型矩阵，囊括 DeepSeek、Qwen、GLM、Kimi、MiniMax 等明星模型，深度覆盖编程开发、学术研究与论文创作、数学推理、视觉处理与多模态交互、对话与长文本处理五大核心场景。</p>
<h2>2.3. 开发者套餐</h2>
<p>算纽开发者套餐，专为学生、独立开发者及中小团队量身定制，以超高性价比解锁顶级大模型编程能力，让每一份开发需求都能高效落地。</p>
<p>套餐核心优势直击开发痛点：成本颠覆性降低，计费低至传统tokens计费的一折，大幅压缩开发成本；模型自由切换，无需冗余购买多平台会员，一键直达GLM-4.7、MiniMax-M2.1、Kimi-K2三大顶级编程模型，最新最强的模型能力随心选；高效创作不等待，生成速度媲美同类高级套餐，助力快速完成代码编写、调试、优化等核心工作。</p>
<p>更有7天免费体验限时开启！零成本即可抢先体验顶级模型的强悍编程能力，轻松开启高效开发新体验。</p>
<p>​</p>
<ul>
<li>官方网址：<a href="https://gpunexus.com/signup?aff=c1xh" rel="noopener noreferrer">https://gpunexus.com/</a></li>
<li>咨询电话：010-53650986</li>
<li>联系邮箱：data@chengfangtech.com</li>
</ul>
]]></description><pubDate>2026-01-14 02:18:35</pubDate></item><item><title>helix-kanban 终端内的多窗口看板</title><link>https://rustcc.cn/article?id=56234088-880c-4fc8-8281-726abca68b8a</link><description><![CDATA[<h1>Kanban</h1>
<p>一个终端看板应用，灵感来自 <a href="https://helix-editor.com/" rel="noopener noreferrer">Helix 编辑器</a>的键位设计。</p>
<h2>预览</h2>
<p><img src="https://raw.githubusercontent.com/menzil/helix-kanban/master/screenshoot.png" alt="Kanban TUI 截图"></p>
<h2>特性</h2>
<ul>
<li>📁 <strong>基于文件存储</strong> - 使用 Markdown 文件和 TOML 配置，易于版本控制</li>
<li>🎯 <strong>多项目支持</strong> - 支持全局项目和本地项目（<code>.kanban/</code>）</li>
<li>⌨️  <strong>Helix 风格键位</strong> - 符合直觉的键盘快捷键</li>
<li>🪟 <strong>窗口管理</strong> - 支持垂直/水平分屏，同时查看多个项目，自动保存和恢复工作区布局</li>
<li>🎨 <strong>现代 TUI</strong> - 基于 ratatui 的美观终端界面</li>
<li>📝 <strong>Markdown 支持</strong> - 任务使用 Markdown 格式，支持外部编辑器</li>
<li>🔍 <strong>任务预览</strong> - 内置预览和外部预览工具支持</li>
<li>⚙️  <strong>自动配置</strong> - 首次运行自动检测编辑器和预览器</li>
</ul>
<h2>安装</h2>
<h3>从 crates.io 安装</h3>
<pre><code>cargo install helix-kanban
</code></pre>
<h3>从源码构建</h3>
<pre><code>git clone https://github.com/menzil/helix-kanban.git
cd helix-kanban
cargo build --release
</code></pre>
<h2>快速开始</h2>
<p>首次运行会显示欢迎对话框，自动检测系统编辑器和 Markdown 预览器：</p>
<pre><code>hxk
</code></pre>
<h3>输入法切换（macOS）</h3>
<p>为了更好的输入体验，在正常模式下自动切换到英文输入法，在对话框模式（如创建/编辑任务）时保持用户的输入法。</p>
<p><strong>推荐安装 im-select 工具：</strong></p>
<pre><code># 使用 Homebrew 安装
brew install im-select

# 或者使用 curl 安装
curl -Ls https://raw.githubusercontent.com/daipeihust/im-select/master/install_mac.sh | sh
</code></pre>
<blockquote>
<p>注意：如果不安装 im-select，程序仍可正常运行，只是不会自动切换输入法。</p>
</blockquote>
<h3>配置管理</h3>
<p>查看当前配置：</p>
<pre><code>hxk config show
</code></pre>
<p>设置编辑器：</p>
<pre><code>hxk config editor nvim
hxk config editor "code --wait"
</code></pre>
<p>设置 Markdown 预览器：</p>
<pre><code>hxk config viewer glow
hxk config viewer "open -a Marked 2"
</code></pre>
<h2>键位绑定</h2>
<h3>基础导航</h3>
<table>
<thead>
<tr>
<th>键位</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>j</code> / <code>↓</code></td>
<td>下一个任务</td>
</tr>
<tr>
<td><code>k</code> / <code>↑</code></td>
<td>上一个任务</td>
</tr>
<tr>
<td><code>h</code> / <code>←</code></td>
<td>左边的列</td>
</tr>
<tr>
<td><code>l</code> / <code>→</code></td>
<td>右边的列</td>
</tr>
<tr>
<td><code>q</code></td>
<td>退出程序</td>
</tr>
<tr>
<td><code>ESC</code></td>
<td>取消/返回</td>
</tr>
<tr>
<td><code>:</code></td>
<td>命令模式</td>
</tr>
<tr>
<td><code>?</code></td>
<td>显示帮助</td>
</tr>
<tr>
<td><code>Space</code></td>
<td>打开命令菜单</td>
</tr>
</tbody>
</table>
<h3>任务操作</h3>
<table>
<thead>
<tr>
<th>键位</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>a</code></td>
<td>创建新任务</td>
</tr>
<tr>
<td><code>e</code></td>
<td>编辑任务标题</td>
</tr>
<tr>
<td><code>E</code></td>
<td>用外部编辑器编辑任务</td>
</tr>
<tr>
<td><code>v</code></td>
<td>预览任务（TUI 内）</td>
</tr>
<tr>
<td><code>V</code></td>
<td>用外部工具预览任务</td>
</tr>
<tr>
<td><code>d</code></td>
<td>删除任务</td>
</tr>
<tr>
<td><code>H</code></td>
<td>任务移到左列</td>
</tr>
<tr>
<td><code>L</code></td>
<td>任务移到右列</td>
</tr>
<tr>
<td><code>J</code></td>
<td>任务在列内下移</td>
</tr>
<tr>
<td><code>K</code></td>
<td>任务在列内上移</td>
</tr>
</tbody>
</table>
<h3>项目管理</h3>
<table>
<thead>
<tr>
<th>键位</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>n</code></td>
<td>新建本地项目 [L]</td>
</tr>
<tr>
<td><code>N</code></td>
<td>新建全局项目 [G]</td>
</tr>
<tr>
<td><code>Space f</code></td>
<td>快速切换项目</td>
</tr>
<tr>
<td><code>Space p o</code></td>
<td>打开项目</td>
</tr>
<tr>
<td><code>Space p n</code></td>
<td>创建新项目</td>
</tr>
<tr>
<td><code>Space p d</code></td>
<td>删除项目</td>
</tr>
<tr>
<td><code>Space p r</code></td>
<td>重命名项目</td>
</tr>
<tr>
<td><code>Space r</code></td>
<td>重新加载当前项目</td>
</tr>
<tr>
<td><code>Space R</code></td>
<td>重新加载所有项目</td>
</tr>
</tbody>
</table>
<h3>窗口管理</h3>
<table>
<thead>
<tr>
<th>键位</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>Space w w</code></td>
<td>下一个窗口</td>
</tr>
<tr>
<td><code>Space w v</code></td>
<td>垂直分屏</td>
</tr>
<tr>
<td><code>Space w s</code></td>
<td>水平分屏</td>
</tr>
<tr>
<td><code>Space w q</code></td>
<td>关闭窗口</td>
</tr>
<tr>
<td><code>Space w h</code></td>
<td>聚焦左面板</td>
</tr>
<tr>
<td><code>Space w l</code></td>
<td>聚焦右面板</td>
</tr>
<tr>
<td><code>Space w j</code></td>
<td>聚焦下面板</td>
</tr>
<tr>
<td><code>Space w k</code></td>
<td>聚焦上面板</td>
</tr>
</tbody>
</table>
<h3>命令模式</h3>
<p>按 <code>:</code> 进入命令模式，支持的命令：</p>
<ul>
<li><code>:q</code> / <code>:quit</code> - 退出应用</li>
<li><code>:open</code> / <code>:po</code> - 打开项目</li>
<li><code>:new</code> / <code>:pn</code> - 创建新项目（全局）</li>
<li><code>:new-local</code> / <code>:pnl</code> - 创建新项目（本地）</li>
<li><code>:add</code> / <code>:tn</code> - 创建新任务</li>
<li><code>:edit</code> / <code>:te</code> - 编辑任务</li>
<li><code>:view</code> / <code>:tv</code> - 预览任务</li>
<li><code>:reload</code> / <code>:r</code> / <code>:refresh</code> - 重新加载当前项目</li>
<li><code>:reload-all</code> / <code>:ra</code> / <code>:refresh-all</code> - 重新加载所有项目</li>
<li><code>:vsplit</code> / <code>:sv</code> - 垂直分屏</li>
<li><code>:hsplit</code> / <code>:sh</code> - 水平分屏</li>
<li><code>:help</code> / <code>:h</code> - 显示帮助</li>
</ul>
<h2>数据存储</h2>
<h3>全局项目</h3>
<p>全局项目存储在 <code>~/.kanban/projects/</code> 目录下。</p>
<h3>本地项目</h3>
<p>在任何目录下按 <code>n</code> 创建本地项目，会在当前目录的 <code>.kanban/</code> 下存储：</p>
<pre><code>your-project/
├── .kanban/
│   └── kanban-project/
│       ├── .kanban.toml
│       ├── todo/
│       ├── doing/
│       └── done/
└── ... (你的其他文件)
</code></pre>
<h3>项目结构</h3>
<pre><code>project-name/
├── .kanban.toml          # 项目配置
├── todo/                 # Todo 任务
│   ├── 001.md
│   └── 002.md
├── doing/                # 进行中任务
│   └── 003.md
└── done/                 # 完成的任务
    └── 004.md
</code></pre>
<h3>任务文件格式</h3>
<p>任务以 Markdown 格式存储：</p>
<pre><code># 任务标题

created: 2025-12-10T10:30:00+08:00
priority: high

任务的详细描述内容...

## 子任务

- [ ] 子任务 1
- [x] 子任务 2
</code></pre>
<h3>配置文件</h3>
<p>应用配置存储在 <code>~/.kanban/config.toml</code>：</p>
<pre><code>editor = "nvim"
markdown_viewer = "glow"

# 隐藏的全局项目列表（软删除）
hidden_projects = ["old-project", "archived-project"]
</code></pre>
<h3>工作区状态保存</h3>
<p>应用会自动保存窗口布局和工作状态，下次启动时恢复：</p>
<p><strong>保存内容</strong>：</p>
<ul>
<li>分屏结构（垂直/水平分割）</li>
<li>每个窗格打开的项目</li>
<li>当前选中的列和任务</li>
<li>聚焦的窗格</li>
</ul>
<p><strong>保存位置</strong>：</p>
<ul>
<li>全局工作区：<code>~/.kanban/workspace.toml</code> - 在任何目录启动时使用</li>
<li>本地工作区：<code>.kanban/workspace.toml</code> - 在项目目录下启动时优先使用</li>
</ul>
<p><strong>使用场景</strong>：</p>
<ul>
<li>经常需要同时查看多个项目？设置好分屏布局后，下次启动自动恢复</li>
<li>在不同项目目录工作？每个目录都有自己独立的工作区布局</li>
<li>想要重置布局？使用命令 <code>:reset-layout</code> 恢复默认单窗格</li>
</ul>
<p><strong>示例工作区配置</strong> (<code>workspace.toml</code>)：</p>
<pre><code># 自动生成，通常无需手动编辑
focused_pane = 2
next_pane_id = 4

[[panes]]
id = 0
type = "horizontal_split"
left = 1
right = 2

[[panes]]
id = 1
type = "leaf"
project = "work-project"
selected_column = 1
selected_task_index = 0

[[panes]]
id = 2
type = "leaf"
project = "personal-project"
selected_column = 0
selected_task_index = 2
</code></pre>
<h2>开发</h2>
<pre><code># 运行开发版本
cargo run

# 运行测试
cargo test

# 构建 release 版本
cargo build --release
</code></pre>
<h2>致谢</h2>
<ul>
<li>键位设计灵感来自 <a href="https://helix-editor.com/" rel="noopener noreferrer">Helix Editor</a></li>
<li>UI 框架使用 <a href="https://github.com/ratatui-org/ratatui" rel="noopener noreferrer">ratatui</a></li>
</ul>
<h2>许可证</h2>
<p>MIT OR Apache-2.0</p>
]]></description><pubDate>2025-12-11 10:37:54</pubDate></item></channel></rss>