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

关于Rust中引用变量销毁时机及一段代码输出结果的疑问

关于Rust中引用变量销毁时机及一段代码输出结果的疑问

嘿,我来帮你拆解这段代码的执行逻辑,搞明白为什么输出是YZX~

先把你的代码贴出来方便对照:

struct A(&'static str);

impl A {
    fn as_ref(&self) -> &Self { &self }
}

impl Drop for A {
    fn drop(&mut self) {
        print!("{}", self.0);
    }
}

fn main() {
    let a = A("X");
    let a = A("Y").as_ref();
    print!("Z");
}

咱一步步捋清楚每一步的执行和变量销毁时机:

  • 第一步:创建第一个A实例
    执行let a = A("X");时,会生成一个持有字符串"X"的A实例,我姑且叫它a_x,并绑定到变量a上。这时候a_x好好待在栈上,还没到销毁的时候。

  • 第二步:重新绑定变量a,临时对象提前销毁
    到let a = A("Y").as_ref();这一步,事情就有意思了:

    1. 先创建一个持有"Y"的临时A实例a_y;
    2. 调用a_y的as_ref()方法,返回对a_y的引用;
    3. 把这个引用赋值给变量a,直接覆盖了之前a_x的绑定。
      这里最关键的点是:这个临时对象a_y的生命周期没有被Rust延长——因为它是通过方法调用返回的引用间接绑定到a,不是直接用临时对象的引用来初始化变量。所以这条语句一执行完,a_y就会被立即销毁,触发Drop trait的drop方法,输出Y。
  • 第三步:输出Z
    接着执行print!("Z");,控制台直接输出Z。

  • 第四步:作用域结束,销毁剩余实例
    当main函数跑完,整个作用域开始清理剩下的变量。这时候之前的a_x虽然绑定被覆盖了,但它一直没被销毁,直到作用域结束才会被处理,销毁时触发drop方法输出X。

把这些输出按顺序串起来,就是你看到的YZX啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 16:29:50