RUST / CHAPTER 11

Generic borrowing and lifetime relationships

Advanced

Describe which input can support a returned reference.

By the end of this chapter

  • Relate output borrows to input borrows
  • Reject references to local owned data
  • Use owned results when data must outlive inputs

The idea

A lifetime annotation describes a relationship among borrows; it does not keep a value alive longer. A function returning one of two borrowed inputs needs a contract that the output remains valid only while the relevant input relationship permits it. The compiler uses that contract to reject callers that would retain a reference beyond the lifetime of its data.

Returning a reference to a locally created String is invalid because that owned allocation is dropped when the function ends. Return the String itself when the caller should own the result. Lifetime annotations cannot repair a fundamentally dangling reference. Prefer the simplest signature that expresses the real ownership arrangement, and use compiler feedback to examine that arrangement rather than treating annotations as arbitrary syntax to silence errors.

Rust example
fn longer<'a>(a:&'a str,b:&'a str)->&'a str{if a.len()>=b.len(){a}else{b}}
fn main(){let first=String::from("map");let second=String::from("loop");println!("{}",longer(&first,&second));}
Result
loop

The function returns a borrow of an input that is still alive in main; lengths here are byte lengths.

Try it yourself

Write a first_nonempty function that borrows one of two string slices and states their shared lifetime relationship.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

CHECK YOUR UNDERSTANDING

Chapter checkpoint

Why can a function not return &local_string when local_string is created inside it?