【发布时间】:2021-07-10 07:24:33
【问题描述】:
我有一个Config 结构来存储全局配置。配置需要传递给不同的结构(抽象层)。为了配置一致性和节省内存,结构存储对全局配置的引用而不是副本。
然后我有如下实现: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();
}
}
正如我的代码注释所说,编译器在删除生命周期标记 (playground) 时拒绝构建。我的问题是为什么需要在函数create_many_b 中为 B 提供明确的生命周期标记。在这个例子中,生命周期省略是如何工作的?由A 通过函数create_many_b 创建的Bs 不应该与A 具有相同的生命周期,而'cfg 的生命周期已经从Config 获得了'cfg 生命周期?
【问题讨论】: