What does this <'a> in a struct mean?

I was doing a little program and I got an error, where I had the following code:

pub struct TemplateHandler {
  dt_base_api_url: &str,
}

the compiler did not let me run this code saying that: expected named lifetime parameter. and: help: consider introducing a named lifetime parameter.

So I did exactly what he asked and my struct looked like this:

pub struct TemplateHandler<'a> {
  dt_base_api_url: &'a str,
}

but what is this <'a> some kind of generic typing? and the nomenclature is really given like this? just an "a" I couldn't find any article that explains this, I don't know if I just didn't read it right.

It’s called a “lifetime parameter”, as you’ll already know by reading the compiler error message you quoted; the name 'a is arbitrary, it could’ve a 'foobar, too. The <'a> introduces it, and then the type of the field uses it. It is a form of generic programming. Learn more here (links to the relevant section in the book “The Rust Programming Language”).

Note that this compiler suggestion is famously misleading. In most cases, especially as a beginner, what you actually want is

pub struct TemplateHandler {
  dt_base_api_url: String,
}

Only if TemplateHandler is a short-lived struct that’s used with some existing longer-lived String containing and owning the data is the struct with a generic lifetime parameter appropriate.

In some cases, when you only expect to be working with string values known at compile-time

pub struct TemplateHandler {
  dt_base_api_url: &'static str,
}

can be a reasonable option, too.

10 Likes

It means that the struct is not self-contained, and is tied to some data stored elsewhere. Fields denoted by 'a only borrow (give a temporary view of) data stored elsewhere. The chain of these annotations is supposed to work like breadcrumbs leading back to the scope to which the struct is chained to.

To actually store a string in a struct, you have to use an owning type, like:

pub struct TemplateHandler {
  dt_base_api_url: Box<str>,
}

or

pub struct TemplateHandler {
  dt_base_api_url: String,
}

Box<str> is identical to &str, except it holds the data itself, instead of referencing it from somewhere else. String is a growable version of Box<str>.

Because Rust doesn't have garbage collection, the compiler can't let you freely use such structs. This borrowing relationship is very restrictive. Structs bound do temporary scopes are useful only in a very few specific cases. If you're a beginner, you should avoid putting references in structs.

3 Likes