Reputation: 83
I came across the section talking about lifetimes and was a little bit confused at first. So I decided to give it a go by coding a little example. (Playground)
fn main() {
let b = "hello";
let mut d = "Unassigned";
{
let a = "hi";
let c = lifetime(&a, &b);
d = &c;
}
// My confusion happens here, I was expecting a compile-time error
// since the lifetime of 'c' is the same as 'a' which is in the previous block
// from my understanding. But this compiles just fine
println!("{}", d);
}
fn lifetime<'a, 'b>(test: &'a str, test2: &'b str) -> &'a str {
println!("{}, {}", test, test2);
return "returned value of lifetime";
}
From my understanding, the lifetime
function binds the lifetime 'a
to the returned reference value.
So normally I would expect the line println!("{}", d);
to break at compile time with an error referencing the lifetime 'a
being out of scope, which I was wrong.
What did I understand wrong? Why is this code compiling?
I've seen this and that which basically just confused me further, because they somewhat say what I was expecting as a result in the first place.
Upvotes: 2
Views: 85
Reputation: 83
After finding out about contravariance as pointed out in the comment above, I wrote this little snippet (similar to the question)
struct Potato(i32);
fn doesnt_work() {
let b = Potato(1);
let d;
{
let a = Potato(2);
let c = lifetime2(&b, &a);
d = c;
}
// Compile-time error ! Borrowed value does not live long enough.
println!("{}", d.0);
}
fn lifetime2<'a, 'b>(test: &'a Potato, test2: &'b Potato) -> &'a Potato {
return &Potato(test.0);
}
Which now gives the actual expected compile-time error.
It finds out in my original question the lifetime was being inferred as 'static
which is the highest common lifetime of str
references.
Upvotes: 2