Function output decoupling?

hey hello,
i would love to know if there is another way to decouple a function from it's output type
dynamic dispatch sim to work well, but if i can evaluate statically at compile time i would not say no... any idea? thx !

what i simply want is returning an abstract trait instead of concrete type ?

fn main() {
    let a = produce_output(true);
    let b = produce_output(false);
    println!("a->{}", a.traduction());
    println!("b->{}", b.traduction());
}

struct data_to_spanish {
    raw_txt: String,
}
impl traductible for data_to_spanish {
    fn traduction(&self) -> String {
        "el zorro marrón rojizo salta sobre el perro perezoso".to_owned()
    }
}
struct data_to_french {
    raw_txt: String,
}
impl traductible for data_to_french {
    fn traduction(&self) -> String {
        "Le renard brun roux saute par-dessus le chien paresseux".to_owned()
    }
}

trait traductible {
    fn traduction(&self) -> String;
}

fn produce_output(input: bool) -> Box<dyn traductible> {
    if input == true {
        Box::new(data_to_french {
            raw_txt: "the red brown fox jump over the lazy dog".to_owned(),
        })
    } else {
        Box::new(data_to_spanish {
            raw_txt: "the red brown fox jump over the lazy dog".to_owned(),
        })
    }
}

your idea looks fine to me, use a trait object (i.e. Box<dyn Trait>) is a valid solution.

if the condition is calculated at runtime, then you must have a single return type, this "single" type can be a trait object, or a enum.

if the condition can be determined at compile time (e.g. encoded at type level, or as a const generic parameter), it may be possible to use different return types on different conditions, but you must use some generic machinary to encode the types, and the function signature will be more complex.

generally, I would suggest use enum over trait object, unless the set of concrete types is open ended, or it involes external linkage like ffi, etc.

using enum, you can easily "recover" the actual type of the value if needed. and with the help of crates like enum-dispatch, you can also use it like dynamically-dispatched trait objects.

conversely, if you use trait objects, then it's not trivial if you want to recover the erased type.

2 Likes

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.