I have been having a hard time understanding lifetimes and I would appreciate some help understanding some of the subtleties which are usually missing from the resources and other question/answers on here. Even the whole section on the Book is misleading as its main example used as the rationale behind lifetimes is more or less false (i.e. the compiler can very easily infer the lifetimes on the mentioned function).
Having this function (kinda similar to the book) as an example:
fn foo<'a>(x: &'a str, y: &'a str) -> &'a str {
x
}
My understanding is that the explicit lifetimes asserts that the returning reference should not live longer than the shortest of the lifetimes of x
and y
. Or in other words, both x
and y
should outlive the returning reference. (Although I'm completely unsure of what exactly the compiler does, does it check the lifetimes of the arguments and then compares the minimum with with life time of the returning reference?)
But then what would the lifetime mean if we have no return values? Does it imply a special meaning (e.g. compared to using two different lifetimes?)
fn foo<'a>(x: &'a str, y: &'a str) {
}
And then we have structs such as:
struct Foo<'a, 'b> {
x: &'a i32,
y: &'b i32,
}
And
struct Foo<'a> {
x: &'a i32,
y: &'a i32,
}
It seems using the same lifetime for the fields adds some constraints, but what exactly is that constraint which causes some examples not to work?
This one might require a question of its own, but there are a lot of mentions of lifetimes and scopes being different but without elaborating much, are there any resources delving deeper on that, especially also considering non-lexical lifetimes?