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

时间:2015-01-05 18:31:52

标签: rust lifetime

struct Point {
    x: u32,
    y: u32,
}

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

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

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

2 个答案:

答案 0 :(得分:9)

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

相反,你正在做的是提供一个&#34;通用生命周期&#34;在创建结构时将是专门的。这类似于具有类型参数的结构:

struct Foo<T>
    foo: T,
}

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

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

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

这表示只要start 的生命周期超过生命周期,endend就可以不同生命周期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
}