So erhalten Sie ein & dyn T aus einer Box <dyn T> [Duplikat]

Jan 11 2021

Ich versuche, ein &dyn Tvon 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 &Tvon a bekommen können Box<T>. Ich verstehe nicht, warum Sie nicht &dyn Tvon einem bekommen können Box<dyn T>.

Antworten

2 kmdreko Jan 11 2021 at 07:22

Um ein &dyn Tvon 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 &Foovon einem zu bekommen Box<Foo>. Der Grund , dass &bArbeiten 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.