I have a few mathematical objects which I have mostly stripped down to illustrate my questions regarding the idiomatic design of such a collection. All of these objects share a few common variables, but some have additional ones. In this stripped down example, using these variables, I want to calculate function
:
pub trait Function {
function(&self, h: f64) -> f64;
}
// the mathematical objects
pub struct A {
pub dim: usize,
pub len: f64,
}
pub struct B {
pub dim: usize,
pub len: f64,
pub a: f64
}
// and a few more similar structs would follow here
impl Function for A {
fn function(&self, h: f64) -> f64 {
h
}
}
impl Function for B {
fn function(&self, h: f64) -> f64 {
h * self.a
}
}
This works nicely so far, although I’m not sure, if it would be a better approach to put the common variables into some kind of “base struct” like this:
pub struct Base {
pub dim: usize,
pub len: f64
}
pub struct A {
pub base: Base
}
pub struct B {
pub base: Base
pub a: f64
}
However, this wouldn’t really solve my next problem. Say I want to plot function
and in order to determine the domain of the x-axis, I would need the variable len
, like this for A
:
pub fn plot(a: A) {
// determine x-axis
let x_max = a.len * 3.0;
// e.g. plot `a.function` over 0.0..x_max
}
It seems to me, that I would have to implement the plot
function for every single struct I have, because I cannot use a trait object, when I need additional data from a struct. And a function like plot(c: Box<dyn Function>, len: f64)
(maybe also with static dispatch) seems clumsy, as at least I know (in contrast to the compiler) that the field Base.len
will exist for every single case.
Basically, I want a type, which has the trait Function
and which has a few fields, like in this case len
. This sounds very OOP, which got me thinking that I might be taking a completely wrong approach.
What design should I use, to make this all idiomatic Rust and also to make it as general and convenient to use as possible?
1