When I define the following structure:
struct Test<'a> {
a: &'a [i64],
b: Vec<i64>,
}
Both the slice and the vector contain a pointer. Why does the slice require a lifetime, but not the vector?
A vector owns its elements. That means the vector is responsible for allocating and freeing the elements it points to. The lifetime of the vector's elements is the same as the lifetime of the vector itself, so there's no need to specify a lifetime to the Vec
type.
A slice borrows the elements of a vector or array that may be allocated statically or dynamically. The slice must indicate the lifetime of the borrowed elements so that the compiler can make the necessary safety checks.
Another way to express this is by comparing the sequence of events between the two options.
For a vector:
Vec
is allocated. No storage is allocated for the elements initially (when the Vec
is empty).Vec
stores a pointer to that storage.Vec
itself is freed.For a slice:
EDIT
Generally speaking, a lifetime annotation is required on borrowed pointers (&'a X
), on types that contain borrowed pointers (X<'a>
, where X
is a struct
or enum
that has a member that is a borrowed pointer) and on trait objects/constraints (X+'a
, where X
is a trait
) when those types are used as members of a struct
or enum
.
On let
bindings and on the right-hand side of the as
operator, you usually write borrowed pointer types without a lifetime annotation (i.e. just &X
), because the compiler infers the lifetime in that case.
What you need to remember is that lifetime annotations are necessary when dealing with borrowed pointers, either directly or indirectly.
If you want to learn more about ownership, borrowing and lifetimes, I suggest you read the Rust Guide's section on pointers as well as the Rust References and Lifetimes Guide
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With