单一可变所有权:Rust 的“最好特性”背后隐藏着哪些取舍?
原创单一可变所有权:Rust 的“最好特性”背后隐藏着哪些取舍?
Rust 的单一可变引用:核心机制与量化数据
有人说过,Rust 最好的特性是单一可变引用。这话不是随便说说的,它写在原文的开篇,带着一种技术人特有的笃定 来源:原文。我最初读到这句话时愣了一下,因为很多介绍 Rust 的文章都会讲借用检查器,讲所有权,却很少直接点明这一条。单一可变引用,说的就是在某个时刻,某个值只能被一个可变引用占用,别人要么读,要么等。
在 Rust 里,这个机制通过借用检查器实现。每个变量要么是 owned,要么是 shared(immutable)reference,要么是 mutably borrowed 来源:原文。这听起来像是一套死板的规则,但有意思的是,Rust 的引用其实同时在干两件事。它跟踪权限,告诉你能不能改这个值;它还启用了 pass-by-reference,而不是 pass-by-value 来源:原文。这两件事常常被混为一谈,但把它们拆开看,才能理解 Rust 设计的精巧之处。
我甚至想过一个更简单的语言。如果编译器来决定传引用还是传值,那会怎样?作者提出一个具体的假设:在 90% 的情况下,大于 24 bytes(现代 ARM 处理器上的一个经验值)的结构体应该传引用,更小的东西传值 来源:原文。这比例是我从原文里读到的,不是我拍脑袋想的。但 24 bytes 这个数,作者也没给出更细的来源,我也只能姑且把它当作一个经验边界来看。
多源对比:Swift 的 inout 与 JavaScript 的值/引用方案
JavaScript 的处理方式就简单得多。它区分 primitive 类型,这些总是传值,和 object 类型,这些总是传引用 来源:原文。这种设计在语义上很直接,但缺了一样东西。如果你拿到一个对象的引用,你完全可以修改它,语言层面没有任何机制来强制“单一可变所有权”。这意味着两个引用可以同时指向同一个对象,然后同时修改,谁先谁后全看执行顺序。
Swift 选了另一条路。它不用可变引用,而是用 inout 参数。概念上,inout 参数把整个值传进函数,调用结束时,再把可能被修改过的整个值传回来 来源:原文。这表面上把可变引用去掉了,实际上换了一种描述方式。你可以把 `fn a(inout b)` 这个调用脱糖成 `fn a(b) -> b`,然后所有调用都按同样方式重写 来源:原文。我理解这个脱糖的意思,就是把修改和返回合并成一个操作,函数外面的人看不到中间状态。
但 Rust 的方法相对 Swift 有一个优势,你可以创建包含引用的结构体。这在实现 Iterator 时特别重要,因为迭代器通常要持有对集合的引用,同时还要能移动游标 来源:原文。我在 HN 评论区看到一位叫 zioss95 的用户留言说“hi i like what you doing keep up the good work”,看起来是给作者打气,但没有提出实质的技术反例 来源:HN 评论区。这个评论虽然简短,至少说明有人读了这篇文章,并且认同这个方向。
扩展设想:inout 字段与未来挑战
作者进一步设想了一个有趣的结构:`struct Foo { bar: inout Bar }`。这个字段的含义是,bar 临时获得 Bar 值的所有权,但函数结束时必须还回去 来源:原文。我刚开始觉得这不过是把 inout 从函数参数搬到结构体字段里,没什么稀奇的。但再一想,这其实是让结构体也能包含可变引用,用 inout 语义来模拟 Rust 的引用机制。这种需求在实现 Iterator 时会出现,只是相对罕见 来源:原文。
问题在于,这种设计能不能落地?作者承认,它是可解的,方法类似,但“需要归还”这一点是硬性的 来源:原文。我理解这句话的意思是,如果 struct 里嵌了 inout 字段,那么结构体的生命周期就必须保证这个字段在某个时刻被还回去,否则所有权就乱了。这个约束在函数调用里很好处理,因为调用边界清晰;但放到结构体里,情况就复杂了。
更麻烦的是布局问题。作者自己说,Struct 和 Array 的布局比调用约定更关键,因为元素数量可能多得多 来源:原文。如果 struct 里包含一个 inout 字段,编译器怎么排内存?字段的大小和位置会影响整个结构体的布局,而这个布局又会影响数组的存储效率。作者没有给出完整代码实现,只提供了概念性描述,这一点我完全理解,毕竟这还是一个设想中的设计 来源:原文。他说自己“tempted to wait and see”,因为即使在 Rust 里,数组的引用也相对罕见,或许为这种情况做特殊处理反而值得 来源:原文。
我的判断是,Rust 的单一可变引用确实是好东西,它解决了多线程环境下的数据竞争问题,也提供了清晰的权限模型。但把它搬到字段层面,或者用 inout 语义去模拟,会带来布局上的新难题。我不确定作者这个 inout 字段的设计最终能否落地,因为数组布局的代价可能是它最大的拦路虎。至少在目前,它停留在概念阶段,需要更多实现层面的探索。
原文:
Single Mutable Ownership · 来源:Hacker News
参考来源:
作者:itfan123 值班编辑 · 发布于 2026年10月29日
版权声明
所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除
itfan123




