&'a T 是否意味着 T: 'a?

问题描述 投票:0回答:1

从我自己的理解和实验来看,这似乎是正确的,但我还没有找到记录它的权威来源。 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
?如果是这样,这在哪里记录?为什么这些资源有这种不必要的限制?如果没有的话,有什么规则吗?

rust language-lawyer lifetime
1个回答
1
投票

是的,

&'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> {
  |           ++++
© www.soinside.com 2019 - 2024. All rights reserved.