2.5.6 嵌套借用与不变性
2 分钟阅读
译文 · 基于 Learning Rust
嵌套借用与不变性
原文链接: https://quinedot.github.io/rust-learning/st-invariance.html
现在让我们考虑嵌套引用:
&'medium &'long U可以强制转换为&'short &'short U&'medium mut &'long mut U可以强制转换为&'short mut &'long mut U……- ……但不能转换为
&'short mut &'short mut U
- ……但不能转换为
我们说 &mut T 在 T 上是不变的(invariant),这意味着 T 中的任何生命周期都完全不能改变(变长或变短)。在上面的例子中,T 是 &'long mut U,而 'long 不能被改变。
为什么不行?考虑这个例子:
| |
如果允许 'w 比 'static 更短,那么在 bar 返回后,*v 中就会出现悬垂引用。
在使用引用时,你不可避免地会对协变性(covariance)产生直觉——因为外层生命周期很灵活——但最终会遇到不变性(invariance)很重要并导致借用检查错误的情况,因为它(必然地)灵活得多。这只是 Rust 学习经历的一部分。
再来看一个你可能遇到的嵌套引用的性质:
- 你可以从
&'short &'long U得到&'long U:- 直接把它复制出来就行!
- 但你不能通过对
&'short mut &'long mut U解引用来得到&'long mut U。- 你只能重借用一个
&'short mut U。 - 有时可以通过交换或临时移出内部引用来获得
&'long mut U,例如使用mem::swap、mem::replace, 或replace_with。参见可变切片迭代器示例。
- 你只能重借用一个
原因同样是为了防止内存不安全。
此外,
- 你不能从
&'short &'long mut U得到&'long U或任何&mut U- 你只能重借用一个
&'short U
- 你只能重借用一个
回想一下,一旦存在共享引用,就可能同时存在任意数量的副本。因此,只要外层共享引用存在(并可能被用来观察 U),内部的 &mut 就不能以可变或其他独占方式使用。
而一旦外层引用失效,内部的 &mut 就重新生效,必须再次独占,因此也不可能获得 &'long U。