I have a Config struct to store the global config. The config needs to be passed to different structs (abstract layers). For config consistency and saving memory, structs store a reference to the global config instead of a copy.
Then I have the implementation like the following: Playground
/// Global Config
#[derive(Debug)]
struct Config {
pub version: String,
}
/// Layer A
#[derive(Debug)]
struct A<'cfg> {
id: u32,
config: &'cfg Config,
}
/// Layer B
#[derive(Debug)]
struct B<'cfg> {
a_id: u32,
b_id: u32,
config: &'cfg Config,
}
impl<'cfg> A<'cfg> {
pub fn new(id: u32, config: &Config) -> A {
A { id, config }
}
#[allow(unused)]
pub fn version(&self) {
println!("{}_a{}", self.config.version, self.id);
}
pub fn create_many_b(&self) -> Vec<B<'cfg>> { // <-- Removing explicit `'cfg` lifetime for B here makes complier complain
let cfg = self.config;
let mut res = Vec::new();
for id in 0..10u32 {
res.push(B { a_id: self.id, b_id: id, config: cfg });
}
res
}
}
impl<'cfg> B<'cfg> {
pub fn version(&self) {
println!("{}_a{}+b{}", self.config.version, self.a_id, self.b_id);
}
}
fn create_many_a(config: &Config) -> Vec<A> {
let mut res = Vec::new();
for id in 0..5u32 {
res.push(A::new(id, config));
}
res
}
fn main() {
// Create a global config
let cfg = Config { version: "1.0".to_owned() };
println!("cfg pointer: {:p}", &cfg);
// Use the global config to create many `A`s
let a_vec = create_many_a(&cfg);
let mut b_vec = Vec::new();
// then create many `B`s
for a in a_vec.into_iter() {
b_vec.extend(a.create_many_b())
}
for b in b_vec.iter() {
b.version();
}
}
As my code comment said, the compiler rejects building when removing the lifetime mark (playground). My question is why it is required to have an explicit lifetime mark for B in the function create_many_b. How is the lifetime elision work in this example? Shouldn't the Bs created by an A via function create_many_b have the same lifetime as the A, which already has a 'cfg lifetime from the Config?