3

Functions new_foo1 and new_foo2 return the same trait Foo using different patterns. I don't see any functional difference between them besides new_foo1 being more verbose. Is there a preferred way among the two? Is there any subtle ramifications of either pattern?

trait Foo {
    fn bar(&self);
}

struct FooIm {}

impl Foo for FooIm {
    fn bar(&self) {
        println!("bar from FooIm")
    }
}

fn new_foo1<'a>() -> &'a (dyn Foo + 'a) {
    &FooIm {}
}

fn new_foo2() -> Box<dyn Foo> {
    let f = FooIm {};
    Box::new(f)
}

fn main() {
    let f1 = new_foo1();
    let f2 = new_foo2();

    f1.bar();
    f2.bar();
}
pretzelhammer
  • 12,263
  • 15
  • 41
  • 88
Aleksey Kanaev
  • 243
  • 2
  • 8
  • 5
    The main difference should come along once you make `new_foo1` a bit more complicated than just returning a literal ([relevant question on the subject of returning references to local values](https://stackoverflow.com/q/50345139)). Try for example a `FooIm` that contains heap-allocated data such as a `Vec` or a `String`, and as described in the linked duplicate, only `new_foo2` will compile. – E_net4 - Krabbe mit Hüten Sep 22 '20 at 08:45
  • 1
    I see now. But why new_foo1 even exists, if it is so faint? – Aleksey Kanaev Sep 22 '20 at 09:27
  • 2
    @AlekseyKanaev Passing boxes around passes ownership. You often need to pass references around without giving up ownership. This is completely unrelated to trait objects. – Sven Marnach Sep 22 '20 at 09:40
  • 3
    A constructor should always returned an owned object, so in this case returing a reference indeed doesn't make any sense. – Sven Marnach Sep 22 '20 at 09:41

0 Answers0