Cara mendapatkan & dyn T dari Kotak <dyn T> [duplikat]
Saya mencoba mendapatkan a &dyn T
dari 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 &T
dari a Box<T>
. Saya tidak mengerti mengapa Anda tidak bisa mendapatkan &dyn T
dari a Box<dyn T>
.
Jawaban
Untuk mendapatkan &dyn T
dari 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 &Foo
dari a Box<Foo>
. Alasan yang &b
bekerja 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.