Rust inheritence

I want to have an inheritance from API, create the derived object,s and call them from a vector of base objects, for example:

trait base {
    do();
}

struct derive1;

impl base for derive1 {
    do(){
        // do derive1
    }
}

struct derive2;

impl base for derive2 {
    do(){
        // do derive2
    }
}

fn main {
    let vec = vec<dyn base>[derive1, derive2];
    for obj in vec {
        obj.do();
    }
}

example in playground

I want to use additional functions in each derive that are different from the base:

trait base {
    do(&self);
}

struct derive1;

impl base for derive1 {
    do(&self){
        self.handler_derive1_do();
    }
    handler_derive1_do(&self){
        //...
    }
}

struct derive2;

impl base for derive2 {
    do(&self){
        self.handler_derive2_do();
    }
    handler_derive2_do(&self){
        //...
    }
}

fn main {
    let vec = vec<dyn base>[derive1, derive2];
    for obj in vec {
        obj.do();
    }
}

playground example

but I get compilation errors:

error[E0407]: method ------ is not a member of trait -------

I fixed it by wrapping the handler in an object, holding it and calling his functions in the trait function implementation:

trait base {
    do(&self);
}

struct Derive1Handler;

impl Derive1Handler{
    pub fn handler_derive1_do(&self){
        //...
    }
}

struct derive1 {
    handler: Derive1Handler;
}

impl base for derive1 {
    do(&self){
        self.handler.handler_derive1_do();
    }
}

struct Derive2Handler;

impl Derive2Handler{
    pub fn handler_derive2_do(&self){
        //...
    }
}

struct derive2 {
    handler: Derive1Handler;
}

impl base for derive2 {
    do(&self){
        self.handler.handler_derive2_do();
    }
}

fn main {
    let vec = vec<dyn base>[derive1, derive2];
    for obj in vec {
        obj.do();
    }
}

playground example

Does this the solution or can I solve it in more simple and elegant way?

You must use a separate impl block to define methods that aren’t in the trait. The impl Trait for block is only for defining trait implementation and nothing else.

3 Likes

You don't really need the handler structs for your example. You can simply call methods of the specific struct when implementing the trait for it.

Playgorund of your last examples without the handler structs.

2 Likes

Thanks
In my trait I have the most common functions: start, stop, etc...
In my implementation of the function, I don't want to write a long ugly function, I want to divide it to smaller functions, for example:

fn run(&self) {
    self.do_a();
    self.do_b();
    self.do_c();
    self.do_d();
}

How can I do it without adding the smaller functions signatures to the trait?

Perfect, it solved my problem.
I didn't know that functions from one impl have access to another impl.
So it looks like I don't need the factory as well.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.