为何Rust中Box内的值可以被移出?
Rust中Box解引用可移出值的原因解析
先看你测试的代码:
struct S; fn f1() { // test1 let s1 : Box<S> = Box::new(S); let s2 : S = *s1; // The S in s1 is moved to s2; // test2 let mut s3 : Box<S> = Box::new(S); // let s4 : S = *DerefMut::deref_mut(&mut s3); //compile error: cannot move out of a mutable reference. // test3 let mut s5 : &mut S = &mut S; // let s6 :S = *s5; //compile error: cannot move out of a mutable reference. }
你疑惑的点在于:明明不能从引用(test2、test3)里移出值,为什么Box的解引用(test1)可以,而且你原本觉得test1和test2是等价的。
核心区别在于所有权归属:
Box<T>是一个拥有所有权的类型,s1作为Box<S>的所有者,完全拥有内部的S值。当你写*s1时,Rust会直接访问这个被Box持有的所有权值,允许你把它移动到s2中——移动后s1就不再持有任何有效数据,完全符合Rust的所有权转移规则。- test2中调用
DerefMut::deref_mut(&mut s3)得到的是&mut S,这是一个可变借用,它只拥有临时的修改权限,不具备所有权。Rust禁止从借用中移出值,因为这会让原所有者(s3)的状态变得无效,违反了借用的安全性规则。 - test3的
&mut S也是同理,可变引用只是临时的访问权限,不能拿走底层的所有权值。
你觉得test1和test2等价,是混淆了Box<T>的解引用和普通引用的解引用。Box<T>的Deref实现是为了让我们能像使用T一样使用Box<T>,但当你直接对Box<T>执行*操作并赋值时,触发的是所有权转移逻辑,而非普通引用的解引用逻辑。
内容的提问来源于stack exchange,提问作者Joey
相关产品推荐
相关产品推荐

