// 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 } }