Cách nhận & dyn T từ Hộp <dyn T> [bản sao]
Tôi đang cố gắng lấy a &dyn T
từ a Box<dyn T>
, như trong ví dụ sau. Tuy nhiên, nó không biên dịch được.
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)
Thông báo lỗi là
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`
Rõ ràng là bạn có thể nhận được &T
từ a Box<T>
. Tôi không hiểu tại sao bạn không thể nhận được &dyn T
từ a Box<dyn T>
.
Trả lời
Để nhận được &dyn T
từ a Box<dyn T>
, hãy sử dụng &*
:
let c: &dyn MyTrait = &*b;
Các *
được sử dụng để deref hộp vào nội dung của nó ( dyn MyTrait
) và sau đó &
được sử dụng để có được nó như là một tài liệu tham khảo.
Đây cũng là cách "đúng" để lấy a &Foo
từ a Box<Foo>
. Lý do mà &b
các công trình với các loại bê tông là do Derefđặc điểm cho phép &Box<T>
được ép buộc để &T
:
Nếu T triển khai Deref <Target = U> và x là giá trị của kiểu T, thì:
- Giá trị kiểu & T bị ép buộc với giá trị kiểu & U
Lý do nó không hoạt động đối với các đối tượng đặc điểm là nó &dyn MyTrait
có thể hợp lệ &Box<...>
và việc ép buộc không được thực hiện ngay cả khi nó không thành công.