简体   繁体   English

生锈寿命只参考参考文献?

[英]Do rust lifetimes only refer to references?

I'm trying to wrap my head around Rust lifetimes (as the official guides don't really explain them that well). 我正试图把我的头脑包裹在Rust的生命周期中(因为官方指南并没有真正解释它们)。

Do rust lifetimes only refer to references, or can they refer to base/primitive values as well? 生锈时间仅涉及参考,或者它们是否也可以引用基本/原始值?

Lifetimes are the link between values and references to said values. 生命周期是值与对所述值的引用之间的联系。

In order to understand this link, I will use a broken parallel: houses and addresses. 为了理解这个链接,我将使用一个破碎的并行:房屋和地址。

A house is a physical entity. 房子是一个物理实体。 It is built on a piece of land at some time, will live for a few dozen or hundred years, may be renovated multiple times during this time, and will most likely be destroyed at some point. 它建在一块土地上,有时会生活几十年或一百年,在此期间可能会多次翻修,并且很可能在某些时候被毁坏。

An address is a logical entity, it may point to a house, or to other physical entities (a field, a school, a train station, a company's HQ, ...). 地址是一个逻辑实体,它可以指向房屋,或指向其他物理实体(字段,学校,火车站,公司的总部......)。


The lifetime of a house is relatively clear: it represents the duration during which a house is usable, from the moment it is built to the moment it is destroyed. 房屋的使用寿命相对清晰:它代表房屋可用的持续时间,从房屋建造的那一刻到房屋被毁坏的那一刻。 The house may undergo several renovations during this time, and what used to be a simple cabana may end up being a full-fledged manor, but that is of no concern to us; 在这段时间里,这所房子可能经过多次翻修,过去简单的小屋可能最终成为一个完整的庄园,但这对我们来说并不重要; for our purpose the house is living throughout those transformations. 为了我们的目的,这所房子生活在这些转变中。 Only its creation and ultimate destruction matter... even though it might be better if no one happen to be in the bedroom when we tear the roof down. 只有它的创造和最终的破坏才有意义......尽管如果在我们把屋顶向下撕裂时没有人碰巧在卧室里可能会更好。

Now, imagine that you are a real estate agent. 现在,想象一下你是一名房地产经纪人。 You do not keep the houses you sell in your office, it's impractical; 你不保留你在办公室出售的房屋,这是不切实际的; you do, however, keep their addresses! 但是,请保留他们的地址!

Without the notion of lifetime, from time to time your customers will complain because the address you sent them to... was the address of a garbage dump, and not at all that lovely two-story house you had the photography of. 没有终身的概念,你的客户会不时抱怨,因为你发送给他们的地址......是垃圾场的地址,而不是那个可爱的两层楼的房子。 You might also get a couple of inquiries from the police station asking why people holding onto a booklet from your office were found in a just destroyed house, the ensuing lawsuit might shut down your business. 您可能还会从警察局得到一些询问,询问为什么人们在刚刚被摧毁的房子里找到了从您办公室拿到小册子的人,随后的诉讼可能会关闭您的业务。

This is obviously a risk to your business, and therefore you should seek a better solution. 这显然对您的业务构成风险,因此您应该寻求更好的解决方案。 What if each address could be tagged with the lifetime of the house it refers to, so that you know not to send people to their death (or disappointment) ? 如果每个地址都可以标记它所指的房子的生命周期,那么你知道不会让人们去死(或失望)?


You may have recognized the C manual memory management strategy in that garbage dump; 您可能已经在垃圾转储中识别出C手动内存管理策略; in C it's up to you, the real estate agent developer, to make sure that your addresses (pointers/references) always refer to living houses. 在C中,由 房地产经纪人 开发人员来确保您的地址(指针/引用)始终指向生活房屋。

In Rust, however, the references are tagged with a special marker: 'enough ; 然而,在Rust中,引用标记有一个特殊标记: 'enough ; it represents the a lower-bound on the lifetime of the value referred. 它表示所引用值的生命周期的下限。

When the compiler checks whether your usage of the reference is safe or not, it asks the question: 当编译器检查您对引用的使用是否安全时,它会询问以下问题:

Is the value still alive ? 这个价值还活着吗?

It does not matter whether the value will be there for a 100 years afterward, as long as it lives long 'enough for the use you have of it. 不要紧的值是否将在那里为100年后,只要活得长'enough了,你有它的用途。

No, they refer to values as well. 不,他们也提到价值观。 If it is not clear from the context how long they will live, they have to be annotated as well. 如果从背景中不清楚他们将活多久,他们也必须注释。 It is then called a lifetime bound. 然后它被称为终身绑定。

In the following example it is necessary to specify that the value, the reference is referring to, lives at least as long as the reference itself: 在下面的示例中,有必要指定引用的值至少与引用本身一样长:

use std::num::Primitive;

struct Foo<'a, T: Primitive + 'a> {
    a: &'a T
}

Try deleting the + 'a and the compiler will complain. 尝试删除+ 'a ,编译器会抱怨。 This is required since T could be anything implementing Primitive . 这是必需的,因为T可以是实现Primitive任何东西。

Yes, they only refer to references, however those references can refer to primitive types. 是的,它们只引用引用,但是这些引用可以引用原始类型。 Rust is not like Java (and similar languages) that make a distinction between primitive types, which are passed by value, and more complex types (Objects in Java) that are passed by reference. Rust不像Java(和类似的语言)那样区分原始类型(通过值传递)和更复杂的类型(Java中的对象),它们通过引用传递。 Complex types can be allocated on the stack and passed by value, and references can be taken to primitive types. 复杂类型可以在堆栈上分配并按值传递,并且可以将引用转换为基本类型。

For example, here is a function that takes two references to i32 's, and returns a reference to the larger one: 例如,这是一个函数,它接受对i32的两个引用,并返回对较大引用的引用:

fn bigger<'a>(a: &'a i32, b: &'a i32) -> &'a i32 {
    if a > b { a } else { b }
}

It uses the lifetime 'a to communicate that the lifetime of the returned reference is the same as that of the references passed in. 它使用生命周期'a来表示返回引用的生命周期与传入的引用的生命周期相同。

When you see a lifetime annotation (eg 'a ) in the code, there's almost always a reference , or borrowed pointer , involved. 当您在代码中看到生命周期注释(例如'a )时,几乎总是涉及引用借用指针

The full syntax for borrowed pointers is &'a T . 借用指针的完整语法是&'a T 'a is the lifetime of the referent . 'a指涉对象的一生。 T is the type of the referent. T是指示物的类型。

Structs and enums can have lifetime parameters. 结构和枚举可以具有生命周期参数。 This is usually a consequence of the struct or enum containing a borrowed pointer. 这通常是包含借用指针的struct或enum的结果。 When you store a borrowed pointer in a struct or enum, you must explicitly state the referent's lifetime. 将借用指针存储在结构或枚举中时,必须明确说明指示对象的生命周期。 For example, the Cow enum in the standard library contains a borrowed pointer in one of its variants. 例如,标准库中的Cow枚举包含其中一个变体中的借用指针。 Therefore, it has a lifetime parameter that is used in the borrowed pointer's type to define the referent's lifetime. 因此,它有一个生命参数,用于借用指针的类型来定义指示对象的生命周期。

Traits can have type bounds and also a lifetime bound. 特征可以具有类型边界,也可以具有生命周期限制。 The lifetime bound indicates the largest region in which all the borrowed pointers in a concrete implementation of that trait are valid (ie their referents are alive). 生命期界限表示该特征的具体实现中所有借用指针有效的最大区域(即它们的指示对象存活)。 If the implementation contains no borrowed pointers, then the lifetime is inferred as 'static . 如果实现不包含借用指针,那么生命周期将被推断为'static Lifetime bounds can appear in type parameter definitions, in where clauses and on trait objects. 生命周期边界可以出现在类型参数定义中, where子句和trait对象中。

Sometimes, you might want to define a struct or enum with a lifetime parameter, but without a corresponding value to borrow from. 有时,您可能希望使用lifetime参数定义结构或枚举,但没有相应的值来借用。 You can use a marker type, such as ContravariantLifetime<'a> , to ensure the lifetime parameter has the proper variance ( ContravariantLifetime corresponds to the variance of borrowed pointers; without a marker, the lifetime would be bivariant, which means the lifetime could be substituted with any other lifetime... not very useful!). 您可以使用标记类型,例如ContravariantLifetime<'a> ,以确保生命周期参数具有正确的方差( ContravariantLifetime对应于借用指针的方差;没有标记,生命周期将是双变量,这意味着生命周期可能是用任何其他生命代替......不是很有用!)。 See an example of this use case here. 请在此处查看此用例的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM