为啥 Rust 编译器要求我限制泛型类型参数的生命周期(错误 E0309)?
Posted
技术标签:
【中文标题】为啥 Rust 编译器要求我限制泛型类型参数的生命周期(错误 E0309)?【英文标题】:Why does the Rust compiler request I constrain a generic type parameter's lifetime (error E0309)?为什么 Rust 编译器要求我限制泛型类型参数的生命周期(错误 E0309)? 【发布时间】:2016-12-02 06:31:32 【问题描述】:为什么 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: 'a
部分添加到结构定义中。我想不出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
在块之后会有一个对s
的悬空引用。在这种情况下,它也会抱怨o2
的寿命也不够长。
我想不出一种方法可以让 &'a
引用包含较短生命周期的引用,并且显然编译器知道以某种方式(因为它告诉你添加约束)。但是我认为在某些方面说明限制是有帮助的,因为它使借用检查器不那么神奇:您可以仅从类型声明和函数签名来推断它,而不必查看字段是如何定义的(通常是实现文档中没有的详细信息)或函数的实现方式。
【讨论】:
我同意直言不讳从来都不是一件坏事。我总是问“源是否比目标更长寿”的问题,并且以这种心态很难写出你的例子,因为我隐含地知道编译器会拒绝它。感谢您提供简单而清晰的示例。以上是关于为啥 Rust 编译器要求我限制泛型类型参数的生命周期(错误 E0309)?的主要内容,如果未能解决你的问题,请参考以下文章
generics - 如何在Rust中添加一个泛型类型实现另一泛型类型的约束?