Cách nhận & dyn T từ Hộp <dyn T> [bản sao]

Jan 11 2021

Tôi đang cố gắng lấy a &dyn Ttừ 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 &Ttừ a Box<T>. Tôi không hiểu tại sao bạn không thể nhận được &dyn Ttừ a Box<dyn T>.

Trả lời

2 kmdreko Jan 11 2021 at 07:22

Để nhận được &dyn Ttừ 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 &Footừ a Box<Foo>. Lý do mà &bcá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 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.