I'd like to initialize a Rust struct with types that depend on each other, i.e. the last struct field depends on a variable constructed for another field.
Example
You can also find the (hopefully?) minimal reproducible example in this Rust playground.
My structs:
pub struct NeedToRelyOnThis {
}
pub struct Breaking {
}
impl Breaking {
pub fn new() -> Self {
Self {}
}
}
pub struct Depending<'a> {
needed: &'a NeedToRelyOnThis,
breaking: &'a Breaking
}
impl<'a> Depending<'a> {
pub fn new(needed: &'a NeedToRelyOnThis, breaking: &'a Breaking) -> Self {
Self { needed, breaking }
}
}
This is working fine:
pub struct BaseWorking<'a> {
needed: &'a NeedToRelyOnThis,
d: Depending<'a>
}
impl<'a> BaseWorking<'a> {
pub fn new(needed: &'a NeedToRelyOnThis, breaking: &'a Breaking) -> Self {
Self {
needed,
d: Depending::new(needed, breaking)
}
}
}
While this is not:
pub struct BaseBroken<'a> {
needed: &'a NeedToRelyOnThis, // by reference is necessary
breaking: Breaking,
d: Depending<'a>
}
impl<'a> BaseBroken<'a> {
// compile without this function and there won't be any errors
pub fn new(needed: &'a NeedToRelyOnThis) -> Self {
Self {
needed,
breaking: Breaking::new(),
// here I want to pass in a reference to the newly created instance of
// `Breaking` into the "constructor" of `Depending`
// It fails as the variable "breaking" cannot be found which is understandable.
d: Depending::new(needed, breaking) }
}
}
Context & my attempts
I've seen this question, however I don't understand how I can apply the only answer to my problem.
If it was possible to defer initialization, I could do something like this:
pub fn new(needed: &'a NeedToRelyOnThis) -> Self {
let mut res = Self {
needed,
breaking: Breaking::new()
}
res.d = Depending::new(needed, &res.breaking);
res
}
which does not work as we have to initialize all struct field at once. Creating it from parts as seen in this playground founders on borrowed values not living long enough. (I found the playground from this comment).
Background: In my code the BaseBroken
struct is a struct implementing an algorithm. NeedToRelyOnThis
is a mathematical graph that gets passed to the algorithm from outside (here the variable needed
). The algorithm class holds some fields to outsource some calculations. One type needs a reference to the other type to access certain information during the calculation.
I'm open for answers proposing a better design concerning the hierarchy of these structs should it turn out that this is really not easily achievable in Rust. In Java and other languages, it'd be possible to do this since the fields of the class/struct can be set one after the other in a proper constructor, but of course Rust is not Java ;)