1 rust
我发现以下内容很难理解:
fn main() {
let mut x: i32 = 10;
{
let y: &mut i32 = &mut x;
*y += 10;
println!("y={}", *y);
let z: &&mut i32 = &y;
// z += 10; // error[E0368]: binary assignment operation `+=` cannot be applied to type `&mut i32`
// *z += 10; // binary assignment operation `+=` cannot be applied to type `&mut i32`
// **z += 10; //cannot assign to data in a `&` reference
}
println!("x={}", x);
}
Run Code Online (Sandbox Code Playgroud)
当我包含 时*z += 10
,错误消息是:
fn main() {
let mut x: i32 = 10;
{
let y: &mut i32 = &mut x;
*y += 10;
println!("y={}", *y);
let z: &&mut i32 = &y;
// z += 10; // error[E0368]: binary assignment operation `+=` cannot be applied to type `&mut i32`
// *z += 10; // binary assignment operation `+=` cannot be applied to type `&mut i32`
// **z += 10; //cannot assign to data in a `&` reference
}
println!("x={}", x);
}
Run Code Online (Sandbox Code Playgroud)
这与y += 10;
既然*z
有类型&mut i32
,与 相同y
,为什么可以*y
用来更新 的值x
,但**z
不能呢?
mut
是缩写unique
“可变”和“唯一”之间的界限很模糊,但在这种情况下“可变”可能会导致错误的直觉。&mut
引用确实是唯一的引用:它们不能使用别名。如果您有 a &mut T
,您知道当引用存在时,将不会通过任何其他引用T
访问(无论是改变还是只是读取) 。
(虽然您通常需要唯一的引用来改变值,但有些引用允许别名和突变。&Cell<T>
其中之一是:您不需要对 a 进行唯一访问Cell
来改变其内容。&mut
引用始终是唯一的。)
编译器可以利用引用不能使用别名的知识&mut
来执行优化。Rustonomicon 的别名部分有更多详细信息。
&
参考文献是共享参考文献&
另一方面,引用总是可以被其他&
引用别名。任何需要对 a 进行唯一访问的内容都T
必须保证不能使用其他引用来访问T
。但 a&&mut T
不能保证这一点,因为它可能被另一个 别名——不会保留&&mut T
对 a 的独占访问。T
但您仍然可以使用 a&&mut T
来获取常规&T
,因为这不需要对&mut T
.
当然,这都是由 Rust 的类型系统强制执行的。考虑如何定义Deref
和:DerefMut
Deref::deref
接受&self
并返回&Self::Target
。因此,您不需要对 的唯一访问权限self
即可获得对 的共享访问权限*self
。DerefMut::deref_mut
需要&mut self
返回&mut Self::Target
。因此,您确实需要唯一的访问权限才能self
获得对 的唯一访问权限*self
。还有一件事阻止您&mut T
通过简单地取消引用 a 来获得 a &&mut T
:
&mut
参考文献没有实现Copy
。