以下代码
struct Cat<'a, T> {
coolness: &'a T,
}
抱怨说
error[E0309]: the parameter type `T` may not live long enough
--> src/main.rs:2:5
|
1 | struct Cat<'a, T> {
| - help: consider adding an explicit lifetime bound `T: 'a`...
2 | coolness: &'a T,
| ^^^^^^^^^^^^^^^
|
note: ...so that the reference type `&'a T` does not outlive the data it points at
--> src/main.rs:2:5
|
2 | coolness: &'a T,
| ^^^^^^^^^^^^^^^
使用明确的生命周期绑定,它会编译。当我实例化T
为&i32
的结构时,尽管每个引用具有不同的生命周期,但代码会编译。我的理解是编译器看到内部&
比外部&
更长:
struct Cat<'a, T>
where
T: 'a,
{
coolness: &'a T,
}
fn main() {
let b = 10;
{
let c = &b;
{
let fluffy = Cat { coolness: &c };
}
}
}
Cat { coolness: &c }
是否扩展为Cat { coolness: &'a &'a i32 }
?对于更多嵌套引用,内部引用是否也具有相同的生命周期等等?
答案 0 :(得分:4)
Cat { coolness: &c }
是否扩展为Cat { coolness: &'a &'a i32 }
?
是的,Cat
最终会引用一个引用。这可以通过以下代码编译来证明:
let fluffy = Cat { coolness: &c };
fn is_it_a_double_ref(_x: &Cat<&i32>) {}
is_it_a_double_ref(&fluffy);
但是,每个参考文献的生命周期不一定相同。
我的理解是编译器看到了内部和外部。超出外部&amp;
没错。这恰恰是T: 'a
界限发挥作用的地方。
起初的生命时间限制有点难以理解。他们对T
中包含的引用进行了限制。例如,给定绑定的T: 'static
,不包含任何引用的类型,或仅包含'static
引用的类型,例如i32
和&'static str
满足边界,而包含非'static
引用的类型,例如&'a i32
,不要,因为'a: 'static
是假的。更一般地,给定绑定T: 'a
,类型T
满足绑定,如果'x
上的每个生命周期参数T
,'x: 'a
为真(类型为没有生命周期参数可以满足条件。
立即返回您的代码。让我们给这些参考文献命名。我们会说coolness
的类型是&'fluffy &'c i32
。 'c
是变量c
的生命周期,'fluffy
是变量fluffy
的生命周期(反直觉地,生命周期编码借用范围,而不是指示对象的生命周期)虽然编译器会检查借用是否超出指示对象的生命周期)。这意味着Fluffy
的类型为Cat<'fluffy, &'c i32>
。 &'c i32: 'fluffy
是否属实?
要检查&'c i32: 'fluffy
是否为真,我们需要检查'c: 'fluffy
是否为真。 'c: 'fluffy
为真,因为c
之后变量fluffy
超出了范围。