下面的代码
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 }
吗?内部引用是否也假定相同的生存期,以此类推,以获取更多嵌套引用? 最佳答案
是的,Cat
以引用的引用结尾。可以通过以下代码编译来证明这一点:
let fluffy = Cat { coolness: &c };
fn is_it_a_double_ref(_x: &Cat<&i32>) {}
is_it_a_double_ref(&fluffy);
但是,每个引用的生命周期不一定相同。
这是正确的。这正是
T: 'a
绑定(bind)起作用的地方。首先,一生难以理解的界限。他们对
T
中包含的引用进行了限制。例如,给定绑定(bind)的T: 'static
,不包含任何引用或仅包含'static
引用的类型,例如i32
和&'static str
满足限制,而包含非'static
引用的类型,例如&'a i32
,不要,因为'a: 'static
是false。更一般而言,如果对于T: 'a
上的每个生存期参数T
,'x
为true(没有生存期参数的类型都微不足道地满足该限制),则给定绑定(bind)的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
为true,因为变量c
在fluffy
之后超出范围。关于rust - 了解Rust中参数化结构的生命周期,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49093143/