Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do lifetimes in Rust work for a function?

Tags:

rust

lifetime

In the definition of lifetime_things, the lifetime of 'b is longer than 'a, but actually when I call this function, x1 is longer than y1, but this can compile successfully:

//here you could see 'b:'a means, the lifetime of b should be larger than a,
fn lifetime_things<'a,'b:'a>(x:&'a String, y:&'b String) ->&'a String {
  if x.len() > y.len() {
    &x
  } else {
    &y
  }
}

fn main() {
let z: i32;
    let x = String::from("1");
    let x1=&x;
    {
        let y = String::from("2");
        let y1=&y;
        println!("{}",lifetime_things(x1,y1));
    }
}

But here you could see the lifetime of x1 should be larger than y1 so why can this compile successfully as well?

like image 272
Edward Alric Avatar asked Oct 21 '25 00:10

Edward Alric


1 Answers

'b: 'a means 'b must outlive 'a, which in turn means whenever 'a is live, so must 'b. Crucially, this is a larger than or equals relationship. Also notice that lifetimes don't work like types. When a function takes an 'v reference, any lifetime ('w) will be accepted as long as 'w: 'v.

So, where is 'a live? In the body of the function and whenever the returned string reference is used after the call. We can visualize it like this:

fn lifetime_things<'a,'b:'a>(x:&'a String, y:&'b String) ->&'a String {
  if x.len() > y.len() {                         // <-+
    &x                                           //   |
  } else {                                       //   |
    &y                                           //   +----+
  }                                              //   |    |
}                                                // <-+    |
                                                 //        |
fn main() {                                      //        +-- 'a
let z: i32;                                      //        |
    let x = String::from("1");                   //        |
    let x1=&x;                                   //        |
    {                                            //        |
        let y = String::from("2");               //        |
        let y1=&y;                               //        |
        println!("{}",lifetime_things(x1,y1));   // <------+
    }
}

Notice, that since the value returned by lifetime_things is only printed, 'a is only live on the line println!("{}",lifetime_things(x1,y1)); (exclusing lifetime_thingss body).

So, to call lifetime_things we simply need the both arguments to at least be live at the call. This holds for both x1 and y1, so it all checks out.

like image 110
Emoun Avatar answered Oct 26 '25 16:10

Emoun



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!