struct Point {
x: u32,
y: u32,
}
struct Line<'a> {
start: &'a Point,
end: &'a Point,
}
此处,start
和end
字段唯一可能的选项是使其生命周期与包含它们的Line
变量相同或更长。我甚至无法想象如何使用终身说明符来表示字段的寿命更短。
为什么我必须在这里明确指定生命周期?在这种情况下是不可能的,如果是这样,为什么不呢?
答案 0 :(得分:9)
定义结构时,您不会在结构的生命周期和字段的生命周期之间建立关系。正如您所指出的,字段中的引用具有比结构更长寿命。
相反,你正在做的是提供一个&#34;通用生命周期&#34;在创建结构时将是专门的。这类似于具有类型参数的结构:
struct Foo<T>
foo: T,
}
构造结构时,编译器将插入适当的生命周期(或类型),然后检查所有内容是否仍然有效。
另一件事是你可以相互指定的生命周期:
struct Line<'a, 'b: 'a> {
start: &'a Point,
end: &'b Point,
}
这表示只要start
的生命周期超过生命周期,end
和end
就可以不同生命周期start
。
为什么编译器不对结构进行终身省略?似乎在精神生锈中这样做
(强调我的)
我实际上认为Rust倾向于显性,特别是在定义顶级项目(如函数,结构)时。
功能的终身省略规则范围非常小,empirically found in RFC 141成功率很高(87%)。这是一个非常好的符合人体工程学的投资回报。
也许在某些时候,结构会出现类似的缺陷,但它还没有足够大的问题呢。如果你对此有强烈的感受,那么我强烈建议在user forum上寻求共识,进入开发者论坛,然后最终制作RFC。
RFC 2093添加了少量推论。在实现之前,您必须表明作为参考的泛型类型需要比引用更长:
struct Foo<'a, T: 'a> {
start: &'a T,
}
在任何情况下,都不会想要这个绑定,所以在实施RFC之后,你可以说:
struct Foo<'a, T> {
start: &'a T,
}
答案 1 :(得分:0)
假设我们有Line
的构造函数:
impl<'a> Line<'a> {
fn new(start: &'a Point, end: &'a Point) -> Line<'a> { // '
Line {
start: start,
end: end,
}
}
}
new
返回Line<'a>
。为了能够使用生命周期参数化类型(就像我们在这里使用Line<'a>
),这种类型必须定义生命周期参数!虽然编译器可以在必要时自动定义生命周期参数,但通过查看源代码中的定义,可以更容易地发现类型具有生命周期参数(或不具有生命周期参数)。
结构和枚举的生命周期参数在借阅检查器中起着重要作用。他们让编译器知道结构保留借用某些值。当您尝试改变有效借用的值时,编译器可以返回错误。
fn main() {
let mut start = Point { x: 2, y: 4 };
let end = Point { x: 7, y: 10 };
let line = Line::new(&start, &end);
start.x = 3; // error: cannot assign to `start.x` because it is borrowed
}