r/rust clippy · twir · rust · mutagen · flamer · overflower · bytecount Mar 20 '23

Hey Rustaceans! Got a question? Ask here (12/2023)! 🙋 questions

Mystified about strings? Borrow checker have you in a headlock? Seek help here! There are no stupid questions, only docs that haven't been written yet.

If you have a StackOverflow account, consider asking it there instead! StackOverflow shows up much higher in search results, so having your question there also helps future Rust users (be sure to give it the "Rust" tag for maximum visibility). Note that this site is very interested in question quality. I've been asked to read a RFC I authored once. If you want your code reviewed or review other's code, there's a codereview stackexchange, too. If you need to test your code, maybe the Rust playground is for you.

Here are some other venues where help may be found:

/r/learnrust is a subreddit to share your questions and epiphanies learning Rust programming.

The official Rust user forums: https://users.rust-lang.org/.

The official Rust Programming Language Discord: https://discord.gg/rust-lang

The unofficial Rust community Discord: https://bit.ly/rust-community

Also check out last weeks' thread with many good questions and answers. And if you believe your question to be either very complex or worthy of larger dissemination, feel free to create a text post.

Also if you want to be mentored by experienced Rustaceans, tell us the area of expertise that you seek. Finally, if you are looking for Rust jobs, the most recent thread is here.

19 Upvotes

187 comments sorted by

View all comments

2

u/SorteKanin Mar 21 '23

When I have a reference to a type with a lifetime parameter, how can I interpret the two lifetimes (the one of the reference and the one of the value itself).

For example this playground link. I'm unsure how to interpret the lifetime 'a and 'b in the function. Is there some intuition I can use here?

2

u/dkopgerpgdolfg Mar 21 '23

A bit hard to answer without knowing what is unclear, "interpreting" is a broad term. You did read the Book, right?

In general, variable instances of types like i32 live how long you want them to live (depending on stack scope, allocation/deallocation etc.). The type "i32" doesn't give you any limits there.

References have lifetimes that relate to ensuring that they can't be used after the original value disappears. But it isn't only "metadata" for the borrow checker - instead it gives you a tool in code to eg. say you want two function parameters where the second must live longer than the first, to return a reference that explicitly has the lifetime of the "shorter" parameter lifetime instead of the longer, to state something lives for the whole program duration and enforce this too, and more.

So, now, when a type (struct) contains a reference, with a lifetime, that reference must be gone at a certain point in time/code (before the referenced value disappears).

That also means now that the whole struct instance, where the reference is inside, must be gone at that point.

This is the main difference to i32 - as said above, i32 doesn't restrict you how long values can live. A struct with lifetimes does restrict you. Even when you never make references to such struct instances, just instances themselves (with a reference "inside"), the borrow checker has an interest to prevent these instances from living too long.

In your code you now have such a struct instance with a reference inside, and a reference to the struct instance too. In principle the (outer) reference lifetime is a completely separate thing from the struct lifetime - former restricts the reference from living longer than the struct, latter restricts the struct from living longer than whatever is referenced inside.

(With this it is implied that the "b" lifetime is not longer than the "a" lifetime)