Reputation: 1636
I want to have:
AppState
that has an AppServices
,AppServices
should have services IdService
,IdService
itself should have access to the AppState
.Below is the idea I came up with, but I am not able to get the lifetime markers done correctly. 🤯
struct IdService<'a> {
name: String,
state: &'a AppState,
}
struct AppServices<'a> {
id: Option<&'a IdService>,
}
struct AppState<'a> {
services: &'a AppServices,
}
impl<'a> AppState<'a> {
pub fn new() -> Self {
AppState {
services: AppServices { id: None },
};
}
}
fn main() {
let mut state = AppState::new();
let id_service = IdService {
name: "test".to_string(),
state: state,
};
let services = AppServices {
id: Some(id_service),
};
state.services = services;
}
Compiler output:
error[E0106]: missing lifetime specifier
--> src/main.rs:3:16
|
3 | state: &'a AppState,
| ^^^^^^^^ expected lifetime parameter
error[E0106]: missing lifetime specifier
--> src/main.rs:6:20
|
6 | id: Option<&'a IdService>,
| ^^^^^^^^^ expected lifetime parameter
error[E0106]: missing lifetime specifier
--> src/main.rs:10:19
|
10 | services: &'a AppServices,
| ^^^^^^^^^^^ expected lifetime parameter
Upvotes: 3
Views: 237
Reputation: 6918
Since your first struct has a reference that has a reference of another struct in itself, you need to specify these children lifetimes too:
struct AppState<'a> {
services: &'a AppServices<'a>,
}
This way you are saying to the compiler that AppState
and AppServices
lifetimes are bound, thus AppServices
members have the lifetime 'a
as well.
However, apart from lifetime issues, you have a cyclic data structure. If you want to share data between structs, there are some specific smart pointers like Rc
and for multithreaded applications Arc
.
Instead of sharing raw pointers of the struct, you can share Arc
smart pointers and mutate data with the help of Mutex
to guarantee single access for a thread.
A solution that uses an Arc
to solve such a cyclic data structure problem.
Upvotes: 4