3

I'm new to Rust, but I think I understand the concept of lifetime parameters well enough. I can see how this would be really useful for methods, when accepting multiple parameters by reference. However, I can't think of an example when a struct would hold references to two different variables with different lifetimes. The Rust book doesn't provide an example of a struct with multiple lifetimes.

The discussion around Elision 2.0 refers to "structs with a single lifetime parameter", and is focused on making it easier to work with types that have only one lifetime parameter, which suggests to me that this is the most common use case for lifetimes - either a struct has no lifetime, or it has one lifetime.

Can anyone provide me with a practical example of a struct with multiple lifetime parameters?

Andrew Williamson
  • 8,299
  • 3
  • 34
  • 62
  • You have an example in a yesterday's answer : https://stackoverflow.com/a/58050166/263525 – Denys Séguret Sep 23 '19 at 08:07
  • The reason to have one lifetime can simply happen to be occurring more than once. Another example, with 3 lifetimes: https://github.com/Canop/termimad/blob/master/src/displayable_line.rs#L11 – Denys Séguret Sep 23 '19 at 08:10
  • The more references, the more lifetimes: that's all – Boiethios Sep 23 '19 at 08:14
  • 1
    Thanks Denys - you can post that as an answer if you want, as those examples have definitely answered my question. The first example being a reference to another reference, that's probably a very common scenario. So far, I've only used Rust from the Rust playground, so I haven't written very complicated code, and haven't had to use a class with multiple lifetimes – Andrew Williamson Sep 23 '19 at 08:22

1 Answers1

2

When you use a reference in a struct, you use a lifetime.

Sometimes you can just use the same lifetime for the various references of your struct, but you can't always do that.

A lifetime is a reference to the time a value is alive (between creation and deletion). And it's a constraint that the borrow checker will check. If you give the same lifetime to two fields, you add a constraint that often can't be verified, thus limiting the possible uses of your struct.

Here's a real world example:

pub struct DisplayableLine<'s, 'l, 'p> {
    pub skin: &'s MadSkin,
    pub line: &'p FmtLine<'l>,
    pub width: Option<usize>, // available width
}

The struct itself is usually short lived. The skin and the line come from different origins. You could have a skin you just make for a display and that you want to immediately drop. Or a line you just made while you keep your skin around. Giving the same lifetime to both fields would be more limiting than necessary.

Of course when your struct is always referring to values that are created together and dropped together, having two lifetimes isn't necessary. But in practice this is rare.

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • I think "absurdly" might be an overstatement. Perhaps you could give an example of how it would be limiting to have the same lifetime bound for two of these fields? References with a longer lifetime are subtypes of references with shorter ones, so using the same lifetime twice in a struct is _usually_ not a big problem because the struct itself can't outlive the shorter lifetime anyway. – Peter Hall Sep 23 '19 at 12:53
  • 1
    @PeterHall Most examples come from real world complexity and it's not easy to come up with a small and obvious example when two fields of a struct must have different lifetimes in a simple scenario. [Here's one](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=17d4393f34b01c5bb5622b10b1809c79). In any case I remove the "absurdly" word. – Denys Séguret Sep 23 '19 at 14:10
  • @DenysSéguret, in your playground example, I noticed that the second lifetime parameter can be removed from the `lg` function (which still requires two for BiRef). Is there a scenario where a function requires more than one lifetime parameter? – Steven Shaw Jan 25 '20 at 01:47