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

Rust中Box指向对象被移动后的Drop调用逻辑疑问

Rust中Box指向对象被移动后的Drop调用逻辑疑问

首先咱们先还原你的问题场景:你观察到这段代码里Drop只被调用了一次,想搞清楚背后的逻辑:

In the following code 'Drop' is being called only once:

#[derive(Default)]
struct MyStruct
{
    my_int: i32,
    my_vec: Vec<i32>,
}

impl Drop for MyStruct {
    fn drop(&mut self) {
        println!("Dropping MyStruct");
    }
}

fn main() {

    {
    let my_box =std::boxed::Box::new(MyStruct::default());

        {
            let my_ref = *my_box;
    

        } // DROP IS CALLED HERE

    } // NOTHING IS CALLED HERE 
}

你的疑问是:是编译器知道Box已经不指向任何东西了所以不调用Box的Drop,还是Box确实被调用了Drop,但它知道里面已经没有MyStruct了所以不触发对应的Drop?

接下来咱们拆解清楚背后的逻辑:

  • 首先,当你执行let my_ref = *my_box;这一行时,你是把Box包裹的MyStruct完整地移动出来了。这时候my_box就变成了一个“空箱子”——它不再拥有堆上的MyStruct实例,那个值的所有权完全转移给了my_ref。
  • 当内部作用域结束时,my_ref被销毁,所以会调用MyStruct的drop方法,这就是你看到打印输出的来源。
  • 而当外部作用域结束时,my_box这个Box实例本身确实会被销毁,它的drop方法也确实会被调用。但Box的drop逻辑很明确:它只会在自己还持有堆上值的所有权时,才会清理堆内存并触发内部值的drop。现在里面的内容已经被移走,Box就只是个空壳,所以它的drop执行时啥也不用做,自然不会有额外的打印。

这里核心是Rust的移动语义在起作用:一个值只能被一个所有者持有,当你把Box里的值移走后,Box就失去了对它的所有权,后续销毁Box时自然不需要再管这个值的生命周期——毕竟那个值已经被my_ref接手,并且已经被销毁过一次了,Rust绝对不会允许同一个值被drop两次。

备注:内容来源于stack exchange,提问作者Zebrafish

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 08:43:02