How to make a method call a function that calls a method?

Hi,

what i want to achieve is having a trait with default implementations defined by functions so that implementing structs can have slightly modified behaviour: call the functions but then do something additional.
In OOP terms that would be: i want to call the method of the super class in the derived class.

This gives method cannot be invoked on a trait object though:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=cad3a8b183520bced40cd61b6a307725

Any idea?

You could change the Signature of your default implementation to something Llke this:
fn default_impl<T: Trait>(t: &T){}

(I'm on my phone right now so sorry for not giving a complete example)

Also, from the minimal example, you could just move the content from the default impl functions into the trait functions, but I guess you explicitly want to have the code in different functions?

The trick you want is ?Sized, which you can use like this:

pub trait Foo {
    fn name(&self) -> &str;
    fn method1(&self) {
        default_implementation1(self);
    }
}

pub fn default_implementation1<T: Foo + ?Sized>(foo: &T) {
    println!("Called on {}.", foo.name());
}

playground

2 Likes

Can you explain what that syntax is actually doing here?

It's just that for historic reasons, generic parameters implicitly assume that T is Sized. The question mark turns this implicit assumption off.

1 Like

Thank you.

So if the where Self: Sized statement remains in the trait declaration you only need the change @raidwas suggested to make it compile, right? Does your solution make the implementation more flexible or offer some other advantage?

Compared to where Self: Sized? Yes my solution is strictly more powerful, because you can't call where Self: Sized methods on trait objects (e.g. &dyn Trait), whereas that's not a challenge in my case.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.