1 个不稳定版本
使用旧的 Rust 2015
0.1.0 | 2015年7月23日 |
---|
在 #aliasing 中排名 #9
7KB
73 行代码(不包括注释)
alias
alias
提供了一些在别名时修改数据的基本方法。
lib.rs
:
示例
let mut x = 0;
let y = alias::one(&mut x);
let z = y;
// now we can read/write through multiple references
z.set(10);
y.set(y.get() + 2);
assert_eq!(z.get(), 12);
let mut x = [0, 0, 0, 0];
let y = alias::slice(&mut x);
let z = y;
// now we can read/write through multiple references
for i in 0..4 {
z[i].set(10);
y[i].set(y[i].get() + i);
}
assert_eq!(z[0].get(), 10);
assert_eq!(z[1].get(), 11);
assert_eq!(z[2].get(), 12);
assert_eq!(z[3].get(), 13);
这是为什么可以这样做?
Rust 的安全性保证围绕着如何控制数据在别名/可操作时被别名/可操作。关键的是共享(不可变)和唯一/可变的引用类型 &
(和 &mut
)。
后者的基本保证是,如果 &mut T
是可访问的,那么它是唯一可以访问它所指向的 T
的路径。这确保了任意修改是完全安全的,例如,因为没有其他引用,所以没有办法使其他引用失效。
另一方面,&T
引用可以被任意别名(可能在大量线程中),因此默认情况下不能发生修改。但是,可以通过专门控制可以发生什么修改的类型来实现修改,例如 std::cell::Cell<T>
。这种类型是围绕 T
的简单包装,只能与可能的 T
子集一起工作(T: Copy
)。这些类型都假设它们可以完全控制对内部数据的访问:它们协调每次交互。
如果对一个数据片段有唯一的访问权限(&mut T
),那么将它视为别名(&T
)肯定是安全的,也可以将它视为别名和可变的(Cell<T>
)。当存在 &mut T
引用时,没有其他代码可以通过任何其他路径来操作 T
(生命周期确保 Cell<T>
不能超出它的生命周期),因此没有其他代码可以执行任何违反 Cell
控制每次交互的假设的操作。
这同样依赖于 T
→ Cell<T>
是一个有效的转换,即布局是相同的。严格来说,这并不保证,但保持这种方式的可能性很小。(还有一个额外因素是,由于 Cell
限制了对其内部结构的访问方式,理论上可能存在更多的布局优化。)