I'm trying to use a struct with multiple implementations of one method:
trait Trait { fn apply(&self) -> vec<usize>; }
struct Bar<X> { vec: Vec<usize> }
impl<X> Bar<X> {
pub fn new(vec: Vec<usize>) -> Self { Self{vec} }
pub fn test(&self) {
// Things here
println!("Method: {:?}", self.apply());
// Things there
}
}
impl Trait for Bar<ThisWay> {
fn apply(&self) -> Vec<usize> { self.vec.iter().map(|x| x.pow(2)).collect() }
}
impl Trait for Bar<ThatWay> {
fn apply(&self) -> Vec<usize> { self.vec.iter().map(|x| x + 2).collect() }
}
fn main() {
Bar<ThisWay>::new(vec![1,2,3]).test();
Bar<ThatWay>::new(vec![1,2,3]).test();
}
Which would return:
>>> [1,4,9];
>>> [3,4,5];
I know I could create 2 structs implementing these methods differently, but that feels wrong as it's potentially a lot of redundant code. I also know I could have a reference to that implementation method:
trait Trait { fn apply(vec: &Vec<usize>) -> Vec<usize>; }
impl Struct{
// fn new
test(&self, t: &impl Trait) {
// Things here
println!("{:?}", t::apply(&self.vec));
// Things there
}
}
struct ThisWay;
struct ThatWay;
impl Trait for ThisWay {fn apply(vec: &Vec<usize>) -> Vec<usize> {///} };
impl Trait for ThatWay {fn apply(vec: &Vec<usize>) -> Vec<usize> {///} };
fn main() {
let this_way = ThisWay{};
let that_way = ThatWay{};
let problem = Bar::new(vec![1,2,3]);
problem.test(&this_way);
problem.test(&that_way);
}
This approach seems needlessly complicated when I would want to use many arguments inside given struct:
fn hill_climber(&self, nullary_op: &impl NullaryOperator, unary_op: &impl UnaryOperator, ...) {
self.vec = nullary_op();
self.vec = unary_op(&self.vec, self.n, self.m, self.jobs, self.stuff, ...);
}
This seems to be a cursed way of writing code. What happens when a method implementation doesn't use a parameter e.g m
, and other uses that?