I'm quite new to Rust, and I have a question regarding lifetimes I encountered when trying to make a program more clean by moving some code to a function. I have a somewhat minimal example below that reproduces the problem
use std::sync::Arc;
use std::thread;
struct SomeStruct<'a> {
s: &'a str,
}
trait SomeTrait<'a> {
fn new(s: &'a str) -> Self;
}
impl<'a> SomeTrait<'a> for SomeStruct<'a> {
fn new(s: &'a str) -> Self {
Self {
s,
}
}
}
fn f<'a, T: SomeTrait<'a>>(s_arc: Arc<String>){
thread::spawn(move || {
T::new(&s_arc.as_str());
}).join();
}
fn main() {
let k = String::from("Helooo");
let karc = Arc::new(k);
f::<SomeStruct>(Arc::clone(&karc));
}
which results in the following error:
error[E0597]: `s_arc` does not live long enough
--> src/main.rs:22:17
|
20 | fn f<'a, T: SomeTrait<'a>>(s_arc: Arc<String>){
| -- lifetime `'a` defined here
21 | thread::spawn(move || {
22 | T::new(&s_arc.as_str());
| --------^^^^^^^^^^^^^^-
| | |
| | borrowed value does not live long enough
| argument requires that `s_arc` is borrowed for `'a`
23 | }).join();
| - `s_arc` dropped here while still borrowed
Note that the string here is just a stand-in for more complex structs, as is everything else.
Ok, so s_arc
is dropped at the end of f
. But should it not be moved into the closure at row 21? From the error message I conclude that the lifetime parameter 'a
is involved here somewhere.
The thing is, the original code looks something like this (but longer and more noodle-like)
// ... (Same as above)
fn main() {
let k = String::from("Helooo");
let karc = Arc::new(k);
let handle = {
let c_karc = Arc::clone(&karc);
thread::spawn(move || {
SomeStruct::new(&c_karc);
})
};
handle.join().unwrap();
}
For me this looks like basically the same code, but obviously that's not correct.
I assume a simple solution would be to just make SomeStruct
take ownership of s
through something like String
, but is there another solution? Is this perhaps the best option, to avoid lifetimes altogether? The real SomeStruct
mostly contains Arc<T>
fields, though typed as &
references.
Thanks in advance for any help!
Edit: Fixed formatting