I need to take two Vec
s of different concrete types and process each combination of list A and B. I can see two ways to do it:
enum * enum
Wrap the concrete type in an enum, use match, use generic functions in trait signatures.
dyn * dyn
Use trait objects, and never use generic functions in the trait signatures.
Are there any other ways do to this?
My aim is a nested loop where the concrete types of each loop can be different types implementing the same trait, or something semantically equal.
struct S1 {}
struct S2 {}
struct SA {}
struct SB {}
trait TTakerConcrete {
fn do_action_concrete<T: TGiver>(&self, g: &T) {
// Do some custom processing per struct
g.give_data();
}
}
trait TTakerDyn {
fn do_action_dyn(&self, g: &dyn TGiver) {
// Do some custom processing per struct
g.give_data();
}
}
trait TGiver {
fn give_data(&self) -> String {
"diff string per struct".to_string()
}
}
// Nums are takers.
impl TTakerDyn for &S1 {}
impl TTakerDyn for &S2 {}
impl TTakerConcrete for &S1 {}
impl TTakerConcrete for &S2 {}
impl TTakerDyn for S1 {}
impl TTakerDyn for S2 {}
impl TTakerConcrete for S1 {}
impl TTakerConcrete for S2 {}
// Letters are givers.
impl TGiver for &SA {}
impl TGiver for &SB {}
impl TGiver for SA {}
impl TGiver for SB {}
fn dyn_dyn(t: Vec<&dyn TTakerDyn>, g: Vec<&dyn TGiver>) {
for n in t {
for l in &g {
n.do_action_dyn(*l);
}
}
}
fn enum_enum(t: Vec<&Nums>, g: Vec<&Letters>) {
for n in t {
for l in &g {
match n {
Nums::S1(s1) => match l {
Letters::SA(sa) => s1.do_action_concrete(sa),
Letters::SB(sb) => s1.do_action_concrete(sb),
},
Nums::S2(s2) => match l {
Letters::SA(sa) => s2.do_action_concrete(sa),
Letters::SB(sb) => s2.do_action_concrete(sb),
},
};
}
}
}
enum Nums {
S1(S1),
S2(S2),
}
enum Letters {
SA(SA),
SB(SB),
}
fn main() {}