I've tried and failed to fix this relative lifetime issue. Lifetime 'a will outlive 'b, but I don't know how to specify it. Hopefully the playground link below works. How can I specify the relative lifetimes?
Compiling playground v0.0.1 (/playground)
error: lifetime may not live long enough
--> src/lib.rs:21:9
|
16 | fn backtestlib(&mut self){
| ---------
| |
| let's call the lifetime of this reference `'1`
| has type `&mut BacktestLib<'2>`
...
21 | self.string_instances.push(tp);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
error: could not compile `playground` (lib) due to previous error
Hello self-referential-data-type, my old friend
I've come to talk with you again!
Because a vision softly creeping
left its seeds while I was sleeping.
And the vision that was planted in my brain
still remains
within the sound of […]…ah!, where was I !?
Right, answering the question!
Moving BacktestLib is just a way this would create unsafety, and putting it in a box won't tell anything to the compiler. The fundamental problem is that backtestlib only has temporary access to the BacktestLib, but its implementation needs the df_source field to be borrowed (and thus the whole BacktestLib) until the BacktestLib goes out of scope. The only kinda way to require this is by writing a function that takes a &'a mut BacktestLib<'a>, which is generally a big red flag you're doing something wrong/impossible. And in fact calling this function will result in the whole struct being mutably borrowed until it goes out of scope, effectively making that function call the last use of your struct.
That doesn't help. The borrow checker doesn't – can't – know about heap-allocation. A reference derived from a Box has exactly the same relation (in terms of lifetimes) to the Box as a reference pointing to an inline container's element would have.
Just don't create self-referential types, and you will live a long, happy life.
It's not really clear to me. What do you expect to happen when df_source is overwritten? (If you thought this could happen automatically -- it cannot, Rust has no garbage collector.)
So I can only guess at what you meant. Perhaps just have a Vec<String> and push a Clone of the current df_source in backtestlib.
If you go the Rc or Arc route, use Rc<str> or Arc<str>, not Rc<String>. You'll do less allocation but gain reference counting overhead.
Just to be absolutely certain: In case you didn’t click the link in my reply, well, click the link It almost sounds as if you might have not clicked it; since the linked reply contains a whole list of approaches, and your follow-up question here picks up on none of those suggestions…