在 Rust 里为 Arc 实现向下转型:一次自制的自引用指针
来源: wolfgirl.dev — 2026-09-29
概述
作者在写构建驱动时遇到一个并发缓存问题:用 Arc 缓存值可以避免昂贵的克隆,但拿到 Arc 之后,没办法像 &JSON 那样直接模式匹配出内部的 Arc。他真正想要的返回类型是「既拥有值、又能当作借用」,于是借助 Pin 固定地址,再配上一个同时持有值和原始指针的包装类型,手工做出了 Arc 的向下转型。
核心要点
- 把缓存里的值换成 Arc 之后克隆确实变便宜了,但 Arc 无法像 &JSON 那样模式匹配出内部的 String,因为 deref 得到的引用活不过函数体。
- 他想要的返回类型是「拥有值的所有权 + 一个指向其内部的指针」,两者始终绑定,只要拥有者还活着,指针就一直有效。
- 第一次用 transmute 把引用伪造成 &'static 的做法失败了:值在移动进构造函数、取出 deref、再移回父栈帧的过程中地址发生变化,实测两次得到不同的指针地址。
- 修正思路是保证地址稳定:用 std::pin::Pin 把值钉在原地,不允许它再被移动。
- 作者也提醒 Pin 用起来非常难,他在写这篇文章时还在初始实现里发现了缺陷。
金句
生命周期存在的意义正是为了阻止这类 bug,我们那套把引用延长成 'static 的小把戏被戳穿了。
👍 0
👎 0
← 返回 Lobsters 首页