从我自己的理解和实验来看,这似乎是正确的,但我还没有找到记录它的权威来源。 Rust by Example 有一个 bounds 部分,其中写着:
:T: 'a
中的所有引用都必须比生命周期长T
。'a
#[derive(Debug)] struct Ref<'a, T: 'a>(&'a T); // `Ref` contains a reference to a generic type `T` that has // an unknown lifetime `'a`. `T` is bounded such that any // *references* in `T` must outlive `'a`. Additionally, the lifetime // of `Ref` may not exceed `'a`.
但是,这看起来是一个很糟糕的演示,因为
T: 'a
界限似乎并不影响 Ref
的行为。我尝试构造一个比 T
短的 'a
,无论有没有 T: 'a
,都会受到阻碍。更重要的是,定义了without生命周期界限的通用引用可以被当作一个with它:
fn f<'a, T>(r: &'a T) {
g(r) // this compiles
}
fn g<'a, T: 'a>(r: &'a T) {
// ...
}
Rust 参考文献在通用参数部分(
struct Ref<'a, T> where T: 'a { r: &'a T }
)中的一些示例具有类似的结构,但没有详细说明。我浏览了那里的文档,那些关于参考文献和关于生命周期的文档,但找不到链接。
那么
&'a T
是否意味着T: 'a
?如果是这样,这在哪里记录?为什么这些资源有这种不必要的限制?如果没有的话,有什么规则吗?
是的,
&'a T
确实意味着T: 'a
。
总是要求引用对象的寿命必须超过引用的寿命,因为这是安全构建所必需的。但是,在 Rust 1.31 之前,不会推断界限,必须显式提供,如这些问题中所示。
正是 RFC #2093: infer outlives 让编译器推断这些边界,从而允许用户忽略它们。从那时起,Rust by Examples 和 Rust Reference 片段就被过度指定,并且不再需要
T: 'a
。
至少在一个地方
&'a T
不会自动推断 T: 'a
,那就是在为特征定义关联类型时(playground 上的演示),但编译器会引导您显式添加它:
trait MakeRef<'a> {
type Type;
}
impl<'a, T> MakeRef<'a> for Vec<T> {
type Type = &'a T;
}
error[E0309]: the parameter type `T` may not live long enough
--> src/lib.rs:6:17
|
6 | type Type = &'a T;
| ^^^^^ ...so that the reference type `&'a T` does not outlive the data it points at
|
help: consider adding an explicit lifetime bound...
|
5 | impl<'a, T: 'a> MakeRef<'a> for Vec<T> {
| ++++