วิธีรับ & dyn T จากกล่อง <dyn T> [ซ้ำ]
ฉันกำลังพยายามหา a &dyn T
จากBox<dyn T>
ตัวอย่างต่อไปนี้ อย่างไรก็ตามไม่สามารถรวบรวม
trait MyTrait {
}
struct Foo;
impl MyTrait for Foo {}
fn main() {
let b: Box<dyn MyTrait> = Box::new(Foo);
let c: &dyn MyTrait = &b;
}
(https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=69c72904fbceae5b55470a878a441b7d)
ข้อความแสดงข้อผิดพลาดคือ
error[E0277]: the trait bound `Box<dyn MyTrait>: MyTrait` is not satisfied
--> src/main.rs:10:27
|
10 | let c: &dyn MyTrait = &b;
| ^^ the trait `MyTrait` is not implemented for `Box<dyn MyTrait>`
|
= note: required for the cast to the object type `dyn MyTrait`
เป็นที่ชัดเจนว่าคุณจะได้รับ&T
จากไฟล์Box<T>
. ฉันไม่เข้าใจว่าทำไมคุณไม่สามารถรับไฟล์&dyn T
จากไฟล์Box<dyn T>
.
คำตอบ
หากต้องการรับ&dyn T
จาก a Box<dyn T>
ให้ใช้&*
:
let c: &dyn MyTrait = &*b;
*
จะใช้ในการderefกล่องลงในเนื้อหาของ ( dyn MyTrait
) และจากนั้น&
จะใช้ในการได้รับมันเป็นข้อมูลอ้างอิง
นี่เป็นวิธีที่ "ถูกต้อง" ในการรับไฟล์&Foo
จากไฟล์Box<Foo>
. เหตุผลที่&b
ทำงานร่วมกับประเภทคอนกรีตเป็นเพราะDerefลักษณะช่วย&Box<T>
ที่จะข่มขู่เพื่อ&T
:
หาก T ใช้ Deref <Target = U> และ x เป็นค่าประเภท T ดังนั้น:
- ค่าของประเภท & T ถูกบังคับให้เป็นค่าประเภท & U
เหตุผลที่ใช้ไม่ได้กับวัตถุลักษณะนั้น&dyn MyTrait
อาจใช้ได้&Box<...>
และการบังคับไม่ได้พยายามแม้ว่าจะล้มเหลว