> Case in point, my first read on lifetimes just left me confused. So I used Rc<> everywhere and made a perfectly functional program.
Curious, did you run into lifetime issues or just started wrapping everything in Rc<> after reading about lifetimes? Wrapping everything in Rc<> isn't even a bad thing, that's what you have to when you do WASM in a browser.
I still find it confusing sometimes because you're not setting lifetime, you're just giving it a name so that the compiler can reason about it.
Like saying something 'static doesn't make it static, it supposed to mean "live until program closes", but you can totally create things with 'static and free them before program exits.
It's been so long I can barely remember now but I'm pretty sure it was the lifetime propagation that got me... once one struct had it, every struct using that struct needed one, then there was more than one lifetime and combining them (and establishing the rules of how the lifetimes related to each other) bent my brain out of shape. Rc<> let me sidestep all of that.
Yeah, lifetime in structs are PITA. However, IMO using them is "the right choice" only in certain situations where performance hit from not using it is too much. I get why serde uses it, but notice who those don't get exposed to end user that much.
Yeah, once you're putting lifetimes in structs you're liable to run into trouble. In general you only want to do that for structs which are not expected to have long or complicated lifetimes (i.e. if you're expecting it might be allocated on the heap, it's likely too complicated to be workable)
Any time I need to explicitly give a lifetime in a struct I use an Rc or some other container. Iβve been using rust casually for years and every time I try to appease the compiler with lifetimes I realize itβs not worth my time. If someone has a very ELI5 resource that will make me understand when and why to do this Iβd appreciate it.
IMO this is something that should just be handled by extra runtime code or a magically smarter compiler. Lifetime management feels like something that matters in a microcontroller or hyper-optimized setting, but never when Iβm executing code on Apple Silicon for a random application. And yet the language makes simple GC ergonomically painful. I love the language but donβt really need all of that performance. I would gladly take a 1% hit to increment reference counts.
I think lifetimes are best thought of as constraints.
Like `x: Foo<'a>` means "x is constrained by lifetime 'a" as in "x is only guaranteed to be soundly usable if 'a is 'alive'".
With the implicit context of "you are only allowed to use things which are guaranteed to be soundly usable".
And that "moving" is distinct from lifetimes (i.e. if you move x out of scope you just don't have it anymore, while a 'a constraint on x limits where you _can_ "have" it).
Then `'static` basically means "no constraint"/"unconstrained".
So a `x: X + 'static` mean x has no constraints, as long as you have it you can use it.
Where `x: X+'a` (or `X<'a>`) would mean you can _at most_ have x until 'a stops being "alive". (This doesn't mean the data behind X doesn't life longer, just that in that specific place you can't "have" it at most while 'a is alive).
So then if we look at `&'static A` we have a type which 1) is always copied instead of moved, so you always have it while you can have it and 2) you can always have it. As consequence it must life for the whole program execution. Not because `'static` says "until end of program" but because a unconstrained &reference can only be sound if it exist until the end of the program!!
> I still find it confusing sometimes because you're not setting lifetime, you're just giving it a name so that the compiler can reason about it.
With Rc you're telling the compiler "I don't know the lifetime, or can't describe it to you using the Rust type system. Please figure it out at runtime."
Curious, did you run into lifetime issues or just started wrapping everything in Rc<> after reading about lifetimes? Wrapping everything in Rc<> isn't even a bad thing, that's what you have to when you do WASM in a browser.
I still find it confusing sometimes because you're not setting lifetime, you're just giving it a name so that the compiler can reason about it.
Like saying something 'static doesn't make it static, it supposed to mean "live until program closes", but you can totally create things with 'static and free them before program exits.