0

Looking for "blanket" implementation of the method(s) for trait.

Let's say for a trait

pub trait A {
  fn do_a(&self);
}

want to have boxed method that wraps with box, without introducing any additional traits:

fn boxed(self) -> Box<Self>;

I can have another trait to achieve that (playground)

pub trait A {
  fn do_a(&self);
}

pub trait Boxed {
  fn boxed(self) -> Box<Self>;
}

impl<T> Boxed for T
where
  T: A,
{
  fn boxed(self) -> Box<Self> {
    Box::new(self)
  }
}

However, new trait Boxed is required for that.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
tmDDWCzr
  • 3
  • 2
  • I'm pretty sure this falls under rusts philosophy of explicitness. When importing a trait, it should be clear from the trait definition all methods that trait exposes. Any mechanism to add methods to a trait outside its definition breaks that rule. – user1937198 Dec 17 '22 at 17:27
  • 1
    Can you not add `boxed()` directly to `A`? – kmdreko Dec 17 '22 at 17:27
  • 1
    You can create `boxed` as a free-function, but you wouldn't be able to use it like a method. – kmdreko Dec 17 '22 at 17:28

1 Answers1

3

You can add boxed directly to A with a default implementation so that structs won't need to implement it themselves:

trait A {
    fn do_a(&self);
    fn boxed (self) -> Box<Self> 
    where Self: Sized 
    {
        Box::new (self)
    }
}

struct Foo{}

impl A for Foo {
    fn do_a (&self) {
        todo!();
    }
    // No need to redefine `boxed` here
}

fn main() {
    let foo = Foo{};
    let _object: Box<dyn A> = foo.boxed();
}

Playground

Jmb
  • 18,893
  • 2
  • 28
  • 55
  • Yes, default implementation [can be added directly to a trait](https://doc.rust-lang.org/book/ch10-02-traits.html#default-implementations), however the scope of using such trait will be limited, i.e. it can't be used as a `&'a dyn A` form: "A cannot be made into an object: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically" – tmDDWCzr Dec 17 '22 at 18:47
  • @tmDDWCzr You can avoid that by adding a `where Self: Sized` constraint *only* on the method like is shown in [this answer](/a/53989780/15710392). – kmdreko Dec 17 '22 at 19:00
  • @tmDDWCzr See amended answer – Jmb Dec 17 '22 at 19:34