为什么Rust编译器请求我约束泛型类型参数的生命周期(错误E0309)?

为什么Rust编译器发出错误请求我约束以下结构中泛型参数的生命周期?

pub struct NewType<'a, T> {
    x: &'a T,
}
error[E0309]: the parameter type `T` may not live long enough
 --> src/main.rs:2:5
  |
2 |     x: &'a T,
  |     ^^^^^^^^
  |
  = help: consider adding an explicit lifetime bound `T: 'a`...
note: ...so that the reference type `&'a T` does not outlive the data it points at
 --> src/main.rs:2:5
  |
2 |     x: &'a T,
  |     ^^^^^^^^

我可以通过更改来修复它

pub struct NewType<'a, T>
where
    T: 'a,
{
    x: &'a T,
}

我不明白为什么有必要添加T:’结构定义的一部分.我想不出T中包含的数据可以比T的引用更长的方式.x的引用需要比NewType结构更长,如果T是另一个结构,那么它需要满足它包含的任何引用的相同条件.好.

是否有一个特定的例子,这种类型的注释是必要的,还是Rust编译器只是迂腐?

最佳答案
什么T:’a是说T中的任何引用必须比’a’更长.

这意味着你不能做以下事情:

let mut o: Option<&str> = Some("foo");
let mut nt = NewType { x: &o };  // o has a reference to &'static str, ok.

{
    let s = "bar".to_string();
    let o2: Option<&str> = Some(&s);
    nt.x = &o2;
}

这将是危险的,因为在块之后nt会有一个悬空引用.在这种情况下,它也会抱怨o2的寿命也不长.

我想不出一种方法,你可以对包含更短生命周期的引用的东西进行引用,显然编译器以某种方式知道这一点(因为它告诉你添加约束).但是我认为在某些方面有助于说明限制,因为它使借用检查器不那么神奇:你可以仅仅通过类型声明和函数签名来推理它,而不必看看如何定义字段(通常是实现不在文档中的细节)或如何执行函数.

转载注明原文:为什么Rust编译器请求我约束泛型类型参数的生命周期(错误E0309)? - 代码日志