Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a &dyn T from a Box<dyn T> [duplicate]

Tags:

rust

I am trying to get a &dyn T from a Box<dyn T>, as in the following example. However, it fails to compile.

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)

The error message is

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`

It is clear that you can get a &T from a Box<T>. I don't understand why you cant get a &dyn T from a Box<dyn T>.

like image 726
qinsoon Avatar asked Oct 29 '25 20:10

qinsoon


1 Answers

To get a &dyn T from a Box<dyn T>, use &*:

let c: &dyn MyTrait = &*b;

The * is used to deref the box into its contents (dyn MyTrait) and then & is used to get it as a reference.


This is also the "right" way to get a &Foo from a Box<Foo>. The reason that &b works with concrete types is because the Deref trait allows &Box<T> to be coerced to &T:

If T implements Deref<Target = U>, and x is a value of type T, then:

  • Values of type &T are coerced to values of type &U

The reason it doesn't work for trait objects is that &dyn MyTrait could be valid for &Box<...> and the coercion isn't attempted even if it fails.

like image 81
kmdreko Avatar answered Nov 01 '25 11:11

kmdreko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!