简体   繁体   中英

what is the difference between this rust function about lifetime

Rust lifetime concept is so confused for me. I have two functions below:

fn test1<'a, 'b: 'a>(x: &'a u32, y: &'b u32) -> &'a u32 {
    if x > y {
        x
    } else {
        y
    }
}

fn test2<'a, 'b: 'a>(x: &'b u32, y: &'a u32) -> &'a u32 {
    if x > y {
        x
    } else {
        y
    }
}

fn main() {
    let a = 5;

    {
        let b = 6;
        let c = test1(&a, &b);
        println!("{}", c);
    }

    {
        let b = 6;
        let c = test2(&a, &b);
        println!("{}", c);
    }
}

This program can be compiled and result is

6
6

However, I cannot figure out the difference between test1 and test2 Can anybody explain it?

TLDR: There is no practical difference.

What you have to understand is that Rust lifetime indications are not strict equality assertion, instead they denote a "longer than" relationship. So when you write:

fn foo<'a> (x: &'a i32)

You are telling the compiler that: "in order to call foo , there must exist some lifetime 'a and x must live at least as long as 'a (but x may live longer than that)".

Going back to your function definitions:

fn test1<'a, 'b: 'a>(x: &'a u32, y: &'b u32) -> &'a u32

This means:

  • There must exist some lifetime 'a such that x lives at least as long as 'a (but may live longer).
  • There must exist some lifetime 'b that is at least as long as 'a (but may be the same) such that y lives at least as long as 'b (but may live longer).
  • And the return value cannot live longer than 'a .

Since there are no other constraints on 'b , the compiler is always free to pick 'b = 'a and the code will compile as long as the constraints on 'a are satisfied.

When you call the function, the compiler searches for some lifetimes 'a and 'b that match the constraints above:

let a = 5;
{
    let b = 6;
    let c = test1(&a, &b);
    println!("{}", c);
}
  • The return value cannot live longer than 'a so 'a must start at the function call (because the return value does not exist before) and end at the closing brace at the earliest.
  • Here x is a and x must live at least as long as 'a . Since a is defined before the function call and is still alive at the closing brace, everything is fine.
  • Here y is b and y must live at least as long as 'b . If we choose 'b = 'a then everything is fine since b is defined before the function call and lives until the closing brace.

Therefore, the compiler chooses 'a == 'b starting at the function call and ending at the closing brace. Both variables a and b live longer than that but this is fine since lifetime annotations for parameters are lower bounds on the true lifetimes of the corresponding variables.

Note: the same reasoning applies to your second function and again the compiler can always pick 'b = 'a whenever all the other constraints are met.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM