Reputation: 19938
pub struct Foo<'m, T> {
tx: &'m mut T,
}
Here, is 'm
representing the lifetime of the reference tx
or is it specifying how long the T
is going to last?
I believe that it's the former and it means the lifetime of the object of type T
that tx
is referring to must exceed 'm
. Is this the correct understanding?
Upvotes: 0
Views: 371
Reputation: 431589
&'a T
means "I know that a valid value of type T
exists at the address contained in this reference for at least as long as the region of code demarcated by 'a
".
The full answer depends on:
As stated in Why can't I store a value and a reference to that value in the same struct?, the "lifetime" of a value is not what most people expect:
As an analogy, think of it this way: During a person's life, they will reside in many different locations, each with a distinct address. A Rust lifetime is concerned with the address you currently reside at, not about whenever you will die in the future (although dying also changes your address). Every time you move it's relevant because your address is no longer valid.
A non-reference value has one or more lifetimes associated with it between when it is created and when it is destroyed, but on a single line of code it has only one that is relevant.
A reference has two lifetimes associated with it on a single line of code:
Here, the concrete lifetime of a
is [0, 2]. The concrete lifetime of b
is [1, 2]. Since b
refers to a
, that's also a related lifetime:
fn example() {
let a = 42; // 0 A
let b = &a; // 1 | B
println!("{}, {}", a, b); // 2 | |
}
As the reference depth increases, this continues — &&&&i32
has five associated lifetimes.
Most of the time, this doesn't matter because the compiler will automatically collapse lifetimes... when variance allows for it.
Additionally, since your example uses generic types, it's effectively expanded to:
pub struct Foo<'m, T: 'm> {
tx: &'m mut T,
}
That is, if the generic type T
contains any references, they must equal or outlive the lifetime 'm
.
See also:
Upvotes: 1
Reputation: 35560
You are correct: 'm
is the lifetime of the reference. And, since the reference must live to be valid for 'm
, the object it's referencing must live at least as long as 'm
. You can see this in the compiler errors:
This code that tries to create a 'static
reference from a temporary string:
fn main() {
let x: &'static String = &"foo".to_string();
}
errors since the string doesn't live as long as the reference:
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:2:31
|
2 | let x: &'static String = &"foo".to_string();
| --------------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
3 | }
| - temporary value is freed at the end of this statement
A lifetime on the object itself would be denoted with the lifetime in a generic syntax:
pub struct Foo<'a> {
slice_iter: std::slice::Iter<'a, u32>
}
Upvotes: 0