We tell rust to check to see if struct foo lasts as long as its reference.
but what is the meaning of a code like this?
struct foo<'a, 'b>(&'a [i32], &'b i32)
if it doesn’t mean anything, why do we need lifetime specifiers in structs anyway? Rust can just check to see if references inside any struct live long enough. what is the point of declaring only one lifetime ( lets say 'a ) and the puting it before every reference?
Or inside impl block, in this code:
impl<'a> From<&'a [i32]> for Foo
what extra information do we give rust? what does it even mean to declare a lifetime and use it without giving information about lifetime?
We tell Rust that the struct is valid over some region/lifetime 'a that the caller/user determines. In practical terms, it means the struct cannot outlive that lifetime but can live for a shorter one.
Same thing except two distinct lifetimes/regions. Two (or more) distinct lifetime parameters become more important when you have mutable references inside.
Edit: Let me elaborate a bit (I’m on mobile so need a few iterations to fully respond )
You should think of lifetime parameters like generic type parameters - eg struct Foo<T>. Where the type parameter describes something about a type (or maybe nothing at all, if there are no bounds), lifetime parameters describe something about the references the struct holds. Generic lifetime parameters have fewer bounds options than generic type parameters. If you have 1 lifetime parameter, you pretty much can’t say anything else about it. If you have two or more, however, you can express an “outlives” relationship between them - eg 'a: 'b. The other difference is that concrete lifetimes are filled in by the compiler, whereas generic type parameters are filled in/chosen by user code explicitly.
For a struct holding immutable references you can generally get away with a single lifetime parameter for all reference fields in it. The real references can live for different concrete lifetimes but the lifetimes can be “squeezed” down. More precisely, immutable references have a subtyping relationship (aka variance) - a longer lifetime is a subtype of a shorter lifetime, and can be substituted in places where the shorter lifetime is needed. Mutable references, however, do not have this subtyping relationship - they’re invariant. So if you have a struct with, say, one mutable reference with a lifetime 'a, then making other references in that struct have 'a as well will not allow them to have a longer lifetime. That makes sense if you think about it - if this were allowed, then you could potentially set a longer lived reference to point to something that lives for a shorter lifetime, and end up with a dangling reference. So to avoid this, and to allow lifetimes to vary across the reference fields, you would specify a different lifetime parameter for the other references. The compiler then treats them as distinct and allows (lifetime) subtyping.
Let me know if something could use more explanation.
Thus far Rust has preferred to err on the side of explicitness, modulo a few areas that were deemed an ergonomic hit without some implicitness (existing lifetime elision being the poster child). It’s likely this will expand, as that internals thread hints at.