Cara mendapatkan & dyn T dari Kotak <dyn T> [duplikat]

Jan 11 2021

Saya mencoba mendapatkan a &dyn Tdari a Box<dyn T>, seperti pada contoh berikut. Namun, gagal untuk dikompilasi.

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)

Pesan kesalahannya adalah

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`

Jelas bahwa Anda bisa mendapatkan a &Tdari a Box<T>. Saya tidak mengerti mengapa Anda tidak bisa mendapatkan &dyn Tdari a Box<dyn T>.

Jawaban

2 kmdreko Jan 11 2021 at 07:22

Untuk mendapatkan &dyn Tdari a Box<dyn T>, gunakan &*:

let c: &dyn MyTrait = &*b;

Yang *digunakan untuk deref kotak ke dalam isinya ( dyn MyTrait) dan kemudian &digunakan untuk mendapatkan sebagai referensi.


Ini juga merupakan cara yang "benar" untuk mendapatkan a &Foodari a Box<Foo>. Alasan yang &bbekerja dengan jenis beton adalah karena Derefsifat tersebut memungkinkan &Box<T>untuk dipaksa untuk &T:

Jika T mengimplementasikan Deref <Target = U>, dan x adalah nilai tipe T, maka:

  • Nilai tipe & T dipaksakan ke nilai tipe & U

Alasan mengapa itu tidak bekerja untuk objek sifat adalah itu &dyn MyTrait bisa valid &Box<...>dan pemaksaan tidak dicoba bahkan jika gagal.