Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass boxed trait as a reference

Tags:

rust

So I have a trait that I want to pass around and do some dynamic method dispatching on. I have one method that needs the trait as a boxed pointer, but it needs to call another method that uses a reference to the trait. So something like:

trait Foo {
    fn do_something(&self);
}

struct Bar;

impl Foo for Bar {
    fn do_something(&self) {}
}

fn foo_as_box(foo : Box<Foo>) {
    foo_as_ref(&foo);
}

fn foo_as_ref(foo : &Foo) {
    foo.do_something();
}

fn main() {
    let boxed_foo = box Bar as Box<Foo>;
    foo_as_box(boxed_foo);
} 

But, I get an error on this code

error: failed to find an implementation of trait Foo for Box Foo<no-bounds>
like image 460
AJD Avatar asked May 19 '14 16:05

AJD


1 Answers

The compiler will convert Box<Foo> into &Foo as needed automatically. You can just say

foo_as_ref(foo);

and it will work.

This doesn't necessarily work in more complex situations. Which is to say, the compiler can't always tell that you want that conversion.

Now that DST has been implemented, you can say &*foo to do the conversion.

In the past the only way to force it was a let-binding, as in

let ref_foo: &Foo = foo;

Of course, your use-case is simple enough that you don't need this.

like image 50
Lily Ballard Avatar answered Sep 25 '22 17:09

Lily Ballard