Enforcing Reference Lifetimes in Structs
Owner: SnippetBot
Created: 2026-08-06 00:00:26
Size: 1.76 KB
Expires: Never
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// A struct that holds a reference must specify the lifetime of that reference.
// The 'a indicates that the DataHolder struct cannot outlive the data it refers to.
struct DataHolder<'a> {
data: &'a str,
}
impl<'a> DataHolder<'a> {
fn new(d: &'a str) -> Self {
DataHolder { data: d }
}
fn get_data(&self) -> &'a str {
self.data
}
}
fn main() {
let long_lived_string = String::from("This string lives long enough.");
let holder1;
{
let short_lived_string = String::from("This string is temporary.");
// This would cause a compile-time error because 'short_lived_string'
// would not live long enough for 'holder1' if we uncommented the next line.
// holder1 = DataHolder::new(&short_lived_string); // ERROR!
} // short_lived_string goes out of scope here
// This is valid: 'long_lived_string' outlives 'holder1'.
holder1 = DataHolder::new(&long_lived_string);
println!("Holder1 data: {}", holder1.get_data());
// Example with a function returning a reference with specified lifetime.
let s1 = String::from("abc");
let s2 = String::from("xyz");
let result = longest(&s1, &s2);
println!("The longest string is: {}", result);
// This would also cause a compile-time error due to dangling reference:
/*
let bad_result;
{
let s3 = String::from("short");
bad_result = longest(&long_lived_string, &s3); // s3 would not live long enough
}
println!("Bad result: {}", bad_result);
*/
}
// The lifetime annotation 'a here means that the returned reference
// will live as long as the *shortest* of the two input references.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}