考虑以下代码:
let x = String::from("123");
let bx = Box::new(x);
let dbx = *bx;
println!("{}", dbx);
//println!("{}", bx); // error due to ownership move
这里创建了
x
,随后装箱为 bx
,随后 bx
在表达式 *bx
中以某种方式取消装箱。
据我了解,数据的所有权从
x
移动到bx
到dbx
,并且数据本身(至少struct String
占用的内存)从堆栈(x
)复制到堆(由 bx
) 指向堆叠 (dbx
)。
我的主要问题是:编译器如何解释
*bx
?
它看起来不像Deref for Box,因为这意味着声明价值的所有权,并引用价值(
&String
)。
看起来编译器以某种方式将其脱糖为 into_inner,但我不清楚为什么。
那么,这是怎么回事?
额外问题:有没有办法查看代码如何脱糖,或者我该如何揭开 Rust 魔法的神秘面纱。我现在对涉及各种智能指针的自动解除引用特别感兴趣。我尝试过 cargo-inspect 但它在这里似乎没有帮助。
通常你是对的,
*
会经过Deref
或DerefMut
并且只能访问&T
或&mut T
。然而,Box
得到特殊对待,并且编译器允许将移出取消引用。
目前没有任何特征允许对用户定义的类型执行此操作(已经提出了 DerefMove
特征,但据我所知尚未被接受)。所以不需要“脱糖”;只是
*bx
就是您所看到的,剩下的由编译器内部处理。在这种情况下,它真的很“神奇”。您可以看到它没有对
into_inner
进行脱糖,因为当前的实现是使用
*
(source):
pub fn into_inner(boxed: Self) -> T {
*boxed
}
另请参阅: