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:
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
some_data
somewhere other than Outer
,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.
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>, }
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.