简体   繁体   中英

Tell the Rust compiler that the lifetime of a parameter is always identical to a struct's lifetime

Sorry if this is obvious, I'm starting out with Rust.

I'm trying to implement a simple Composition relationship (one object is the single owner of another one, and the inner object is destroyed automatically when the outer object dies).

I originally thought it would be as simple as declaring a struct like this:

struct Outer {
    inner: Inner
}

To my knowledge, that does exactly what I want: the inner attribute is owned by the outer struct, and will be destroyed whenever the outer object disappears.

However, in my case, the Inner type is from a library, and has a lifetime parameter.

// This is illegal
struct Outer {
    inner: Inner<'a>
}

// I understand why, I'm using an undeclared lifetime parameter

I have read a bit on lifetime parameters (but I'm not yet completely used to them), and I'm unsure whether there is some syntax to tell the Rust compiler that “the lifetime this field expects is its owner's“, or whether it's just not possible (in which case, what would be the proper way to architecture this code?).

“the lifetime this field expects is its owner's“,

This is impossible.

Generally, you should understand any type with a lifetime parameter (whether it is a reference &'a T or a struct Foo<'a> or anything else) as pointing to something elsewhere and which lives independently.

In your case, whatever Inner borrows (whatever its lifetime is about) cannot be a part of Outer . This is because if it was, Outer would be borrowing parts of itself, which makes Outer impossible to use normally. (Doing so requires pinning , preventing the struct from moving and thereby invalidating the references, which is not currently possible to set up without resorting to unsafe code.)

So, there are three cases you might have:

  1. Your full situation is

    struct Outer { some_data: SomeOtherType, inner: Inner<'I_want_to_borrow_the_some_data_field>, }

    This is not possible in basic Rust; you need to either

    • put some_data somewhere other than Outer ,
    • use the ouroboros library which provides mechanisms to build sound self-referential structs (at the price of heap allocations and a complex interface),

    or design your data structures differently in some other way.

  2. The data Inner borrows is already independent. In that case, the correct solution is to propagate the lifetime parameter.

     struct Outer<'a> { inner: Inner<'a>, }
  3. There is not actually any borrowed data; Inner provides for the possibility but isn't actually using it in this case (or the borrowed data is a compile-time constant). In this case, you can use the 'static lifetime.

     struct Outer { inner: Inner<'static>, }

You can use a bound on Self :

struct Outer<'a> where Self: 'a {
    inner: Inner<'a>
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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