为什么生命周期不能在结构定义中被省略?

问题描述 投票:9回答:2
struct Point {
    x: u32,
    y: u32,
}

struct Line<'a> {
    start: &'a Point,
    end: &'a Point,
}

在这里,startend字段唯一可能的选项是使其生命周期与包含它们的Line变量相同或更长。我甚至无法想象如何使用终身说明符来表示字段的寿命更短。

为什么我必须在这里明确指定生命周期?在这种情况下是不可能的,如果是这样,为什么不呢?

rust lifetime
2个回答
10
投票

定义结构时,不会在结构的生命周期和字段的生命周期之间建立关系。正如您所指出的,字段中的引用必须比结构更长寿。

相反,你正在做的是提供一个“通用生命周期”,它将在你创建结构时专门化。这与具有类型参数的结构类似:

struct Foo<T>
    foo: T,
}

构造结构时,编译器将插入适当的生命周期(或类型),然后检查所有内容是否仍然有效。

另一件事是你可以相互指定生命周期:

struct Line<'a, 'b: 'a> {
    start: &'a Point,
    end: &'b Point,
}

这说startend可以有不同的寿命,只要end的寿命超过start的寿命。

为什么编译器不对结构进行终身省略?似乎在Rust的精神下这样做

(强调我的)

我实际上相信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,
}

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
}
© www.soinside.com 2019 - 2024. All rights reserved.