2 votes

Comment obtenir un &dyn T à partir d'une Box<dyn T>

J'essaie d'obtenir un &dyn T d'un Box<dyn T> comme dans l'exemple suivant. Cependant, il ne parvient pas à compiler.

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 )

Le message d'erreur est le suivant

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`

Il est clair que vous pouvez obtenir un &T d'un Box<T> . Je ne comprends pas pourquoi vous ne pouvez pas obtenir un &dyn T d'un Box<dyn T> .

0 votes

Cela pourrait être lié au fait que le dyn T n'est pas dimensionné et ne peut donc pas être représenté par un pointeur standard. doc.rust-lang.org/nightly/std/boxed/index.html#mory-layout

4voto

kmdreko Points 3321

Pour obtenir un &dyn T d'un Box<dyn T> utiliser &* :

let c: &dyn MyTrait = &*b;

El * est utilisé pour deref la boîte dans son contenu ( dyn MyTrait ) et ensuite & est utilisé pour l'obtenir comme référence.


C'est aussi la "bonne" façon d'obtenir une &Foo d'un Box<Foo> . La raison pour laquelle &b fonctionne avec des types concrets est que l Deref Le trait permet &Box<T> à être forcée a &T :

Si T implémente Deref<Target = U>, et que x est une valeur de type T, alors :

  • Les valeurs de type &T sont converties en valeurs de type &U.

La raison pour laquelle cela ne fonctionne pas pour les objets traits est que &dyn MyTrait pourrait être valable pour &Box<...> et la coercition n'est pas tentée même si elle échoue.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X