Rust实现Deref trait的自定义类型用*解引用报错与Box<T>行为为何不同?
问题核心原因
你遇到的差异本质上是因为**Box<T>是Rust编译器内置的特殊类型,享有语言层面的专属语法特权**,和你自定义的普通智能指针底层逻辑完全不同。
1. 先纠正你的一个错误认知
你在第一段代码里写的注释 // equivalent to *std::ops::Deref::deref(&boxed) 仅适用于普通自定义智能指针的解引用场景,对Box
- 普通自定义类型实现
Deref后,*运算符的逻辑是:先调用deref()方法返回内部值的共享引用&T,再对引用解引用。对于没有实现Copytrait的类型,你不可能从共享引用里把值移动出来,这就是你的MyBox<T>报错的直接原因。 - 编译器对
Box<T>做了专属处理:直接对Box<T>做*解引用时,会直接把堆上存储的内部值取出来转移所有权,完全绕开了Dereftrait的返回引用逻辑。这个特权目前只给了Box<T>,稳定版Rust暂时不允许自定义智能指针实现这个行为。
2. 关于存储位置的疑问
Box<T>把值存在堆上的特性和这个解引用行为是配套设计的,但不是报错的直接原因:哪怕你自己实现一个把值存在堆上的自定义智能指针,只要没有编译器的特殊处理,一样无法通过*直接解引用移动非Copy类型的内部值。
简易验证
你可以把MyBox<T>存储的类型换成i32这种实现了Copy trait的类型,解引用就不会报错:此时编译器会直接拷贝引用指向的值,不需要移动所有权。
内容的提问来源于stack exchange,提问作者Tristan Young
相关产品推荐
相关产品推荐

