Is it always useful for links in the structure to have the same lifetime
Yes, and he goes beyond the framework. If the times of life were always different from each other, you could not write this function:
fn foo<'a, 'b>(a: &'a str, b: &'b str) -> &str { // What lifetime to return? if (global_random_number() == 42) { a } else { b } }
When applied to a structure, you can have something like this:
struct EvenOrOdd<'a, 'b> { even: &'a str, odd: &'b str, } impl<'a, 'b> EvenOrOdd<'a, 'b> { fn do_it(&self, i: u8) -> &str { if i % 2 == 0 { self.even } else { self.odd } } }
Note that while this compiler does not return a string that the structure itself can survive, and not what was intended. This code does not work, although it should work:
fn foo<'a, 'b>(a: &'a str, b: &'b str) { let result = { EvenOrOdd { even: a, odd: b }.do_it(42) }; println!("{}", result); }
This will work with standardized lifetimes:
struct EvenOrOdd<'a> { even: &'a str, odd: &'a str, } impl<'a> EvenOrOdd<'a> { fn do_it(&self, i: u8) -> &'a str { if i % 2 == 0 { self.even } else { self.odd } } }
This is the opposite of a related answer that contains a comment:
you want to be able to summarize the value and separate its parts after use
In this case, we want to take the aggregated value and combine them.
In more rare cases, you may need to cut a needle between different and standardized life spans:
struct EvenOrOdd<'a, 'b: 'a> { even: &'a str, odd: &'b str, } impl<'a, 'b> EvenOrOdd<'a, 'b> { fn do_it(&self, i: u8) -> &'a str { if i % 2 == 0 { self.even } else { self.odd } } }
Although this is useful when necessary, I cannot imagine crying and gnashing of teeth that could erupt if we had to write this every time.
ignore extra entry
I would not. Having
foo<'a>(Bar<'a>)
definitely better than
foo<'a, 'b', 'c, 'd>(Bar<'a, 'b', 'c, 'd>)
If you do not use additional generic parameters.