从我自己的理解和实验来看,这似乎是真的,但我还没有找到一个权威的来源来证明它.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的行为.我试图构建一个短于'aT的任何try ,无论有没有T: 'a都会受阻.更重要的是,定义without生命周期 界限的通用引用可以被伪装成with它:

fn f<'a, T>(r: &'a T) {
    g(r) // this compiles
}

fn g<'a, T: 'a>(r: &'a T) {
    // ...
}

在第generic parameters节(struct Ref<'a, T> where T: 'a { r: &'a T })中的一些例子中,铁 rust 参考文献有类似的 struct ,但它没有详细说明.我已经翻阅了那里的文档,那些关于参考文献和生命周期的文档,但找不到链接.

那么,&'a T意味着T: 'a吗?如果是,这是在哪里记录的?为什么这些资源会有这种不必要的限制?如果没有,规则是什么?

推荐答案

是的,&'a T确实意味着T: 'a.

一直要求参照物必须超过参照物的使用生命周期 ,因为这是安全旁路施工所必需的.然而,在Rust 1.31之前,不能推断该界限,必须明确提供,如these questions中所示.

正是RFC #2093: infer outlives允许编译器推断这些界限,从而允许用户省略它们.从那时起,Rust by Example和Rust Reference代码段被过度指定,不再需要T: 'a.


至少有一个地方&'a T不会自动推断T: 'a,那就是在为特征(demo on the playground)定义关联类型时,但编译器会 bootstrap 您显式添加它:

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> {
  |           ++++

Rust相关问答推荐

无法理解铁 rust &S错误处理

编译项目期间使用Cargo生成时出现rustc错误

在跨平台应用程序中使用std::OS::Linux和std::OS::Windows

在macro_rule中拆分模块和函数名

如何将实现多个特征的 struct 传递给接受这些特征为&;mut?

rust中的库插件管理器,现在是否可行?

找不到 .has_func 或 .get_func 的 def

在 Rust 中,为什么 10 个字符的字符串的 size_of_val() 返回 24 个字节?

为什么某些类型参数仅在特征边界中使用的代码在没有 PhantomData 的情况下进行编译?

在没有任何同步的情况下以非原子方式更新由宽松原子操作 Select 的值是否安全?

如何使用 Bincode 在 Rust 中序列化 Enum,同时保留 Enum 判别式而不是索引?

缺失serde的字段无法设置为默认值

为什么 `tokio::join!` 宏不需要 Rust 中的 `await` 关键字?

borrow 匹配手臂内部的可变

使用自定义 struct 收集 Vec

如何将 Rust 字符串转换为 i8(c_char) 数组?

将 `&T` 转换为新类型 `&N`

Rust 为什么 (u32, u32) 的枚举变体的大小小于 (u64)?

为什么我不能将元素写入 Rust 数组中移动的位置,但我可以在元组中完成

在 macro_rules 中转义 $ 美元符号