正如标题所述,为什么下面的代码可以编译?
use std::ops::Deref;
struct Foo {}
fn main() {
let b = Box::new(Foo{});
let pb = *b; //works
// let pb = *b.deref(); // error[E0507]: cannot move out of a shared reference
}
对于具有非Copy目标的自定义类型,情况并非如此。
use std::ops::Deref;
struct Foo<T> {
p: T,
}
impl<T> Deref for Foo<T> {
type Target = T;
fn deref(&self) -> &<Self as Deref>::Target {
&self.p
}
}
fn main() {
let f = Foo { p: vec![1u8] };
let pf = *f; // error[E0507]: cannot move out of a shared reference
let pf = *f.deref(); // error[E0507]: cannot move out of a shared reference
}
*Box
不是在做*Box.deref()
吗?
1条答案
按热度按时间eimct9ow1#
*Box
不是在做*Box.deref()
吗?不,不是的。这是编译器魔术的一种情况--
Box
类型有点特殊,编译器会特别对待它。看看
Box
的Deref
实现,我们强烈地感觉到有些不同:如果这是任何其他类型,这将导致无限递归,但deref运算符(
*
)在应用于Box
值时由编译器内部处理。你可以对盒子做的一件特殊的事情是将它包含的值移出,这会产生破坏盒子并释放它的堆分配的副作用。
(Also,不稳定的
Box::into_inner()
关联函数接受boxed: Self
并简单地返回*boxed
,进一步说明了这一点。)