You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 23:00:18