# Lifetimes

* Lifetimes are a way to manage and ensure memory safety by defining the scope for which a reference is valid.
* Prevent dangling references and ensure that references don't outlive the data they point to.
* Lifetime are denoted using (`'`) followed by a name, like `'a`.
* Most of the time, we don't need to explicitly annotate lifetimes because Rust has lifetime elision rules to infer lifetimes in simple cases.
* References:
  * [Lifetimes - Rust By Example](https://doc.rust-lang.org/stable/rust-by-example/scope/lifetime.html)
  * [Validating References with Lifetimes](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html)
  * [Lifetime Elision](https://doc.rust-lang.org/reference/lifetime-elision.html)

## lifetimes1.rs

```rust
// The Rust compiler needs to know how to check whether supplied references are
// valid, so that it can let the programmer know if a reference is at risk of
// going out of scope before it is used. Remember, references are borrows and do
// not own their own data. What if their owner goes out of scope?

// Fix the compiler error by updating the function signature.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

fn main() {
    // You can optionally experiment here.
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_longest() {
        assert_eq!(longest("abcd", "123"), "abcd");
        assert_eq!(longest("abc", "1234"), "1234");
    }
}
```

* This exercise is a bit easy.
* Rust cannot infer the lifetime of input reference in function `longest`.
* So we need to define lifetime explicitly by adding `'a` (you can change the lifetime name with anything you want).
* This is to bind the lifetime of input `x` and `y` into the output of `longest` function.

## lifetimes2.rs

```rust
// Don't change this function.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

fn main() {
    // Fix the compiler error by moving one line.

    let string1 = String::from("long string is long");
    let result;
    {
        let string2 = String::from("xyz");
        result = longest(&string1, &string2);
        println!("The longest string is '{result}'");
    }
}
```

* This exercise is easy.
* The `println` macro is using `result` variables which already out of scope (rust already drop it) so we cannot access it anymore.
* We just need to move the line to inside the bracket.

## lifetimes3.rs

```rust
// Lifetimes are also needed when structs hold references.

// Fix the compiler errors about the struct.
struct Book<'a> {
    author: &'a str,
    title: &'a str,
}

fn main() {
    let book = Book {
        author: "George Orwell",
        title: "1984",
    };

    println!("{} by {}", book.title, book.author);
}
```

* In this exercise we have struct `Book` that hold a reference.
* So we ned to explicitly define lifetime of each reference in the struct so the struct doesn't outlive the reference.
* We can do it like this:

  ```rust
  struct Book<'a> {
      author: &'a str,
      title: &'a str,
  }
  ```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bagus-cahyono.gitbook.io/programming-notes/rust/rustlings_exercise/16_lifetimes.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
