So erhalten Sie ein & dyn T aus einer Box <dyn T> [Duplikat]
Ich versuche, ein &dyn T
von einem zu bekommen Box<dyn T>
, wie im folgenden Beispiel. Es kann jedoch nicht kompiliert werden.
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)
Die Fehlermeldung lautet
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`
Es ist klar, dass Sie eine &T
von a bekommen können Box<T>
. Ich verstehe nicht, warum Sie nicht &dyn T
von einem bekommen können Box<dyn T>
.
Antworten
Um ein &dyn T
von a Box<dyn T>
, verwenden &*
:
let c: &dyn MyTrait = &*b;
Das *
wird verwendet, um die Box in ihren Inhalt zu zerlegen ( dyn MyTrait
) und wird dann &
verwendet, um sie als Referenz abzurufen.
Dies ist auch der "richtige" Weg, um ein &Foo
von einem zu bekommen Box<Foo>
. Der Grund , dass &b
Arbeiten mit konkreten Typen sind , weil das DerefMerkmal ermöglicht &Box<T>
wird gezwungen zu &T
:
Wenn T Deref <Target = U> implementiert und x ein Wert vom Typ T ist, dann:
- Werte vom Typ & T werden zu Werten vom Typ & U gezwungen
Der Grund, warum es für Merkmalsobjekte nicht funktioniert, ist, dass &dyn MyTrait
es für gültig sein könnte&Box<...>
und der Zwang nicht versucht wird, selbst wenn er fehlschlägt.