关于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();这一步,事情就有意思了:- 先创建一个持有"Y"的临时A实例
a_y; - 调用
a_y的as_ref()方法,返回对a_y的引用; - 把这个引用赋值给变量
a,直接覆盖了之前a_x的绑定。
这里最关键的点是:这个临时对象a_y的生命周期没有被Rust延长——因为它是通过方法调用返回的引用间接绑定到a,不是直接用临时对象的引用来初始化变量。所以这条语句一执行完,a_y就会被立即销毁,触发Droptrait的drop方法,输出Y。
- 先创建一个持有"Y"的临时A实例
第三步:输出Z
接着执行print!("Z");,控制台直接输出Z。第四步:作用域结束,销毁剩余实例
当main函数跑完,整个作用域开始清理剩下的变量。这时候之前的a_x虽然绑定被覆盖了,但它一直没被销毁,直到作用域结束才会被处理,销毁时触发drop方法输出X。
把这些输出按顺序串起来,就是你看到的YZX啦~
备注:内容来源于stack exchange,提问作者Congyu WANG
相关产品推荐
相关产品推荐

